Introduction to Generics
In this page:
function name<T>(param: T): T {
return param;
}
Why Generics Are Useful
Generics let one function or class work with many different types without losing information about the specific type actually passed in, unlike using any, which throws that type information away entirely.
Example: Why Generics Are Useful
function identity<T>(value: T): T {
return value; // keeps the exact input type, unlike "any"
}
console.log(identity<string>("hello"), identity<number>(42));
Type Parameters
A type parameter such as T is a placeholder for a concrete type supplied when the generic code is actually used, similar to how a function parameter is a placeholder for a concrete value supplied at call time.
Example: Type Parameters
function wrapInArray<T>(value: T): T[] {
return [value];
}
console.log(wrapInArray(5), wrapInArray("hi"));
Type Inference
TypeScript often infers a generic type from the supplied argument automatically, so explicit type arguments are only needed when the compiler genuinely can't figure out the intended type on its own.
Example: Type Inference
function identity<T>(value: T): T {
return value;
}
console.log(identity(42)); // T inferred as number, no explicit argument needed
Generic Arrays
Generics are commonly combined with arrays to describe the element type while keeping the function reusable across arrays of numbers, strings, or any other type, all through the same generic implementation.
Example: Generic Arrays
function firstItem<T>(items: T[]): T {
return items[0];
}
console.log(firstItem([1, 2, 3]), firstItem(["a", "b"]));
Generic Type Aliases
Type aliases can also have type parameters, making an object shape reusable with different data types plugged in — for example, a generic ApiResponse<T> shape that works whether T is a User, a Product, or anything else.
Example: Generic Type Aliases
type ApiResponse<T> = {
data: T;
status: number;
};
const response: ApiResponse<string> = { data: "OK", status: 200 };
console.log(response);
- Using
anyinstead of a generic, likefunction id(v: any): any, which loses the connection between the input and return types. - Forgetting that
Tis only a placeholder, and writingT.lengthornew T()as if it were a real value. - Passing explicit type arguments that do not match the argument, such as
identity<string>(42), which is an error.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: