TypeScript Intermediate: Generics and Utility Types
Generics
In this lesson you will
- Write a generic function with a type parameter
- Constrain a type parameter with extends
- Create generic interfaces and classes
Introduction
Suppose you write a function that returns the first item of an array. For numbers you would type it number[], for strings string[]. Do you write it once per type? Or use any and lose all type safety? Generics are the answer: write the function once, and let the type be a parameter.
The problem
Here is a function typed with any. It works, but TypeScript forgets what is inside:
A type parameter
A type parameter is a placeholder for a type, written in angle brackets. Convention uses T.
Read <T> as "for some type T". TypeScript works T out from the arguments (inference), so you rarely write first<number>(...) yourself. The return type connects to the input: put in numbers, get a number back.
Quick quiz
In function first<T>(items: T[]): T | undefined, what is T?
More than one type parameter
Constraints with extends
Sometimes T cannot be just anything. If you want to read .length, T must have one. A constraint limits T:
T extends { length: number } means "any type that has at least a numeric length". Strings and arrays qualify, numbers do not.
Generic interfaces and type aliases
Types can take parameters too. This pattern is common for data from a server:
Default type parameters
Give a parameter a default, just like a function argument:
Generic classes
One class now serves stacks of any type, and each stack stays type-safe.
Quick quiz
What does T extends { length: number } mean?
Try it yourself
Write a generic function lastItem<T> that returns the last element of an array, or undefined if the array is empty. Then check what TypeScript says about the type of each result.
Summary
- Generics let one function or type work with many types while staying type-safe.
- A type parameter like
<T>is a placeholder that is filled in by inference or explicitly. T extends Somethingconstrains what T may be.- Interfaces, type aliases and classes can all take type parameters, with optional defaults.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading