Generic Constraints in TypeScript
Generic Constraints in TypeScript
Section titled “Generic Constraints in TypeScript”Basic Constraint
Section titled “Basic Constraint”interface HasLength { length: number;}
function logLength<T extends HasLength>(arg: T): T { console.log(arg.length); return arg;}
logLength("hello"); // OK — string has lengthlogLength([1, 2, 3]); // OK — array has length// logLength(42); // ❌ Error: number has no lengthkeyof Constraint
Section titled “keyof Constraint”function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key];}
const user = { name: "Alice", age: 30, email: "alice@test.com" };const name = getProperty(user, "name"); // type: stringconst age = getProperty(user, "age"); // type: numberConditional Constraints
Section titled “Conditional Constraints”type ExtractStrings<T> = T extends { [K in keyof T]: T[K] extends string ? T[K] : never }[keyof T] ? T : never;
// Self-referential constraintsinterface TreeNode<T extends TreeNode<T>> { value: T; children: TreeNode<T>[];}Real Project Example
Section titled “Real Project Example”// Database entity constraintinterface Entity { id: string; createdAt: Date; updatedAt: Date;}
class Repository<T extends Entity> { async getById(id: string): Promise<T | null> { return db.query(`SELECT * FROM ${this.tableName} WHERE id = $1`, [id]); }
async update(id: string, data: Partial<T>): Promise<T> { // Must keep id, createdAt immutable const { id: _, createdAt: __, ...updatable } = data as any; return db.query(`UPDATE ${this.tableName} SET ... WHERE id = $1`, [updatable, id]); }}Interview Questions
Section titled “Interview Questions”Easy: How do you constrain a generic type parameter?
Medium: What does extends keyof T do in a generic constraint?
Hard: How would you create a self-referential generic constraint?