TypeScript Generics
Write reusable functions and types that work across type parameters
Overview
Generics let you parameterize types. A generic function or interface works with multiple types while preserving type relationships—avoiding any and unsafe casts.
Syntax / Usage
function identity<T>(value: T): T {
return value
}
const n = identity(42) // number
const s = identity('hello') // string
// Multiple type parameters
function pair<A, B>(a: A, b: B): [A, B] {
return [a, b]
}
// Constrained generics
interface HasId { id: string }
function findById<T extends HasId>(items: T[], id: string): T | undefined {
return items.find((item) => item.id === id)
}
// Generic interface
interface ApiResult<T> {
data: T
error: string | null
}
Examples
Generic React props:
interface ListProps<T> {
items: T[]
renderItem: (item: T) => React.ReactNode
keyExtractor: (item: T) => string
}
function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
return (
<ul>
{items.map((item) => (
<li key={keyExtractor(item)}>{renderItem(item)}</li>
))}
</ul>
)
}
Factory with default type:
function createStore<T = string>(initial: T) {
let state = initial
return {
get: () => state,
set: (value: T) => { state = value },
}
}
Common Mistakes
- Over-genericizing simple functions that only use one type
- Forgetting constraints when accessing properties on
T - Using generics when a union or overload is simpler
- Inference failures—annotate call sites when needed
See Also
interfaces utility-types unions type-guards