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
index.ts
and:
  1. Create a generic LoadingState<Data> discriminated union with four statuses:
    • idle β€” no payload
    • loading β€” no payload
    • success β€” carries data of type Data
    • error β€” carries an error string
  2. Implement createSuccess so it returns a success state whose data is the argument you passed in
  3. Implement createError so it returns an error state whose error is the message string you passed in (keep it generic over Data for typing)
  4. Export createSuccess and createError by name

Completion criteria

  • Named exports: createSuccess, createError
  • Success results have status success and preserve the input in data
  • Error results have status error and preserve the message in error
  • Works with string, number, and object data via generics
πŸ’° Model idle, loading, success, and error as exclusive variants of one generic type.

Please set the playground first

Loading "Generic Types"
Loading "Generic Types"