Loading lesson…
Generics let a function work for many types while keeping type safety. The syntax looks scary and the concept is simple.
A generic is a placeholder that TypeScript fills in based on how you call the function. One `identity` works for strings, numbers, and users.
function identity<T>(x: T): T {
return x;
}
const a = identity("hi"); // T = string
const b = identity(42); // T = number
const c = identity({ id: 1 }); // T = { id: number }
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
const n = first([1, 2, 3]); // number | undefinedGenerics carry the concrete type through the function. No `any`, no casting.function byId<T extends { id: string }>(items: T[], id: string): T | undefined {
return items.find((i) => i.id === id);
}
type User = { id: string; name: string };
const users: User[] = [{ id: "u_1", name: "Ada" }];
const u = byId(users, "u_1"); // typed as User | undefined
console.log(u?.name);`extends` says: T can be any type as long as it has an id string. Lets you use i.id safely.The big idea: generics carry types through reusable functions. Add constraints when you need properties, lean on built-in utility types, and stop when it stops helping.
15 questions · take it digitally for instant feedback at tendril.neural-forge.io/learn/quiz/end-progx-ts-generics-creators
What does a generic type parameter represent in TypeScript?
What is the primary benefit of using generics over writing separate functions for each type?
What does the `extends` keyword do when used with a generic type parameter?
When should you prefer `function f(x: string)` over `function f<T extends string>(x: T)`?
What is the difference between `Pick<T, K>` and `Omit<T, K>`?
What does `Record<'a' | 'b', number>` produce?
Why would you add a constraint like `<T extends { name: string }>` to a generic function?
In the function signature `function identity<T>(arg: T): T`, what does the first `T` represent?
What error would TypeScript catch if you called a generic function with an incorrect type that violates its constraint?
You need to create a type for an object that might have some optional properties from a User type. Which utility type should you use?
What is wrong with this code: `function process<T extends object>(item: T) { return item.name; }`?
What is the 'big idea' that the lesson describes about generics?
When is it appropriate to create a custom generic instead of using a built-in utility type?
Consider: `function log<T extends { toString(): string }>(val: T): void`. What types could validly be passed to this function?
A teammate writes `function getProps<T>(obj: T): string[] { return Object.keys(obj); }`. What's wrong with this?