Generic Types
Generic Types
π¨βπΌ Generics aren't just for functionsβyou can create reusable, generic types
and interfaces too!
// Generic type alias
type Container<Value> = {
value: Value
}
// Generic interface
interface Box<Contents> {
contents: Contents
}
// Usage
const stringBox: Box<string> = { contents: 'hello' }
const numberBox: Box<number> = { contents: 42 }
This is exactly how built-in types like
Array<Item> and Promise<ResponseData>
work.π¦ Avoid using generics to hide a cast. This is a common anti-pattern:
// β 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!
This compiles even if the actual data is the wrong shape, which defeats the
purpose of TypeScript. Instead, you should actually validate the data and use
type guards to ensure the data is the correct shape.
π¨ Open
and:
- Create a generic
LoadingState<Data>discriminated union with four statuses:- idle β no payload
- loading β no payload
- success β carries
dataof typeData - error β carries an
errorstring
- Implement
createSuccessso it returns a success state whosedatais the argument you passed in - Implement
createErrorso it returns an error state whoseerroris the message string you passed in (keep it generic overDatafor typing) - Export
createSuccessandcreateErrorby name
Completion criteria
- Named exports:
createSuccess,createError - Success results have status
successand preserve the input indata - Error results have status
errorand preserve the message inerror - Works with string, number, and object data via generics
π° Model idle, loading, success, and error as exclusive variants of one generic
type.


