Generic Types
Generic Types (π solution)
π¨βπΌ You've created reusable generic types!
π¦ The
LoadingState<Data> pattern is extremely useful for modeling async
operations in UI code. Here's how you'd use it:type User = { id: number; name: string }
let userState: LoadingState<User> = { status: 'idle' }
// User clicks "load"
userState = { status: 'loading' }
// Fetch completes successfully
userState = createSuccess({ id: 1, name: 'Ada' })
// Or fetch fails
userState = createError<User>('Network failed')
// Render based on state
function render(state: LoadingState<User>) {
switch (state.status) {
case 'idle':
return 'Click to load'
case 'loading':
return 'Loading...'
case 'success':
return `Hello, ${state.data.name}` // TypeScript knows data exists!
case 'error':
return `Error: ${state.error}` // TypeScript knows error exists!
}
}
This pattern forces you to handle all states and TypeScript narrows the types
automatically based on the discriminated union.
π¦ Avoid using generics to hide a cast. This looks type-safe but is not:
// β Bad: the caller picks the type, not the data
function getData<Data>(): Data {
return fetchData() as Data
}
const user = getData<User>() // Compiles even if fetchData returns wrong shape!
The caller can pick any
Data, so this compiles even when the actual data is
wrong. The generic is just hiding an unsafe cast.

