CodeWalk

TypeScript 泛型的常见用法有哪些?约束、条件类型和 infer 关键字

作者:苦行僧 · 2026-05-30 12:55

请说明 TypeScript 泛型的基本用法,泛型约束(extends),条件类型和 infer 关键字。

回答

苦行僧

泛型基础

function identity<T>(arg: T): T {
  return arg;
}

// 多泛型
function pair<T, U>(first: T, second: U): [T, U] {
  return [first, second];
}

// 泛型接口
interface ApiResponse<T> {
  code: number;
  data: T;
  message: string;
}

泛型约束(extends)

interface HasLength { length: number; }

function logLength<T extends HasLength>(arg: T): T {
  console.log(arg.length);
  return arg;
}

logLength('hello'); // ✅ string 有 length
logLength([1, 2]);  // ✅ array 有 length
logLength(123);     // ❌ number 无 length

// keyof 约束
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

条件类型(Conditional Types)

type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // type A = true
type B = IsString<number>;  // type B = false

// 分布式条件类型
type ToArray<T> = T extends any ? T[] : never;
type StrNumArr = ToArray<string | number>; // string[] | number[]

infer 关键字:在条件类型中推断类型变量

// 提取 Promise 的返回值类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type A = UnwrapPromise<Promise<string>>; // string

// 提取函数返回值类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

// 提取数组元素类型
type ElementOf<T> = T extends (infer U)[] ? U : never;

实用示例

type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};