Functions and generics
TypeScript generics explained simply
TypeScript generics let functions and types work with many values while keeping type safety. Learn syntax, constraints, and when to skip them.
Generics let you write code that works with many types without throwing away type information. You get one function or type definition, and TypeScript still knows what you passed in.
Why generics exist
Say you want a function that returns the first item of an array.
Without generics you pick one type:
function firstNumber(items: number[]) {
return items[0]
}
That works for numbers. For strings you copy the function and change the type. That gets old fast.
You could use any:
function first(items: any[]) {
return items[0]
}
TypeScript stops helping you. You lose autocomplete and compile-time checks.
Generics fix this. You write the function once, and the type follows the argument:
function first<T>(items: T[]) {
return items[0]
}
const n = first([1, 2, 3]) // number | undefined
const s = first(['a', 'b']) // string | undefined
The T is a type parameter. TypeScript fills it in when you call the function.
Generic constraints with extends
Sometimes the generic type must have certain properties.
You restrict it with extends:
interface HasName {
name: string
}
function greet<T extends HasName>(person: T) {
console.log(`Hi ${person.name}!`)
}
greet({ name: 'Flavio', age: 40 })
This is the same idea from the TypeScript tutorial: generics can be limited to a class family or interface.
Generic types and interfaces
Generics are not just for functions. You can type API responses like this:
type ApiResponse<T> = {
data: T
status: number
}
type User = { id: number, name: string }
const res: ApiResponse<User> = {
data: { id: 1, name: 'Flavio' },
status: 200
}
You write ApiResponse once. Swap User for any other type.
Arrays use the same pattern:
const nums: Array<number> = [1, 2, 3]
Array<number> is a generic type. The number inside the angle brackets is the type argument.
When not to use generics
My advice is to skip generics when a plain type works.
If your function only ever handles strings, type it as string[]. No generic needed.
If you reach for generics on the first version of a helper, you might be over-engineering. Start simple. Add a generic when you actually need the same logic for a second type.
Generics shine in reusable utilities, API wrappers, and libraries. For a one-off function in your app, a concrete type is often enough.
Lesson completed