TypeScript条件类型 #
一、条件类型基础 #
1.1 什么是条件类型 #
条件类型根据条件选择两个类型之一,类似于JavaScript的三元运算符。
typescript
type IsString<T> = T extends string ? true : false;
type A = IsString<string>;
type B = IsString<number>;
1.2 基本语法 #
typescript
type Conditional<T> = T extends U ? X : Y;
- 如果
T可以赋值给U,则类型为X - 否则类型为
Y
1.3 简单示例 #
typescript
type IsNumber<T> = T extends number ? 'yes' : 'no';
type A = IsNumber<number>;
type B = IsNumber<string>;
type C = IsNumber<number | string>;
二、条件类型分发 #
2.1 什么是分发 #
当条件类型作用于联合类型时,会自动分发到每个成员:
typescript
type ToArray<T> = T extends any ? T[] : never;
type StrArr = ToArray<string>;
type NumArr = ToArray<number>;
type Mixed = ToArray<string | number>;
2.2 分发过程 #
typescript
type ToArray<T> = T extends any ? T[] : never;
type Result = ToArray<string | number>;
type Result = ToArray<string> | ToArray<number>;
2.3 避免分发 #
使用元组类型避免分发:
typescript
type ToArrayNonDist<T> = [T] extends [any] ? T[] : never;
type Result = ToArrayNonDist<string | number>;
2.4 实际应用 #
typescript
type NonNullable<T> = T extends null | undefined ? never : T;
type A = NonNullable<string | null | undefined>;
type B = NonNullable<null>;
type C = NonNullable<undefined>;
三、infer关键字 #
3.1 什么是infer #
infer用于在条件类型中推断类型,只能在extends子句中使用。
typescript
type UnwrapArray<T> = T extends (infer U)[] ? U : T;
type Str = UnwrapArray<string[]>;
type Num = UnwrapArray<number>;
3.2 推断数组元素类型 #
typescript
type ElementType<T> = T extends (infer E)[] ? E : never;
type A = ElementType<string[]>;
type B = ElementType<number[]>;
type C = ElementType<[string, number]>;
3.3 推断函数返回类型 #
typescript
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
function greet(): string {
return 'hello';
}
type R = ReturnType<typeof greet>;
3.4 推断函数参数类型 #
typescript
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
function add(a: number, b: number): number {
return a + b;
}
type Params = Parameters<typeof add>;
3.5 推断Promise值类型 #
typescript
type Awaited<T> = T extends Promise<infer U> ? U : T;
type A = Awaited<Promise<string>>;
type B = Awaited<Promise<number>>;
type C = Awaited<string>;
3.6 多个infer #
typescript
type UnwrapTuple<T> = T extends [infer A, infer B] ? [A, B] : never;
type Result = UnwrapTuple<[string, number]>;
四、内置条件类型 #
4.1 Exclude #
从类型中排除可以赋值给U的类型:
typescript
type Exclude<T, U> = T extends U ? never : T;
type A = Exclude<'a' | 'b' | 'c', 'a'>;
type B = Exclude<string | number | boolean, number>;
4.2 Extract #
提取可以赋值给U的类型:
typescript
type Extract<T, U> = T extends U ? T : never;
type A = Extract<'a' | 'b' | 'c', 'a' | 'b'>;
type B = Extract<string | number | boolean, number>;
4.3 NonNullable #
排除null和undefined:
typescript
type NonNullable<T> = T extends null | undefined ? never : T;
type A = NonNullable<string | null | undefined>;
type B = NonNullable<null>;
4.4 ReturnType #
获取函数返回类型:
typescript
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
function fn(): string {
return 'hello';
}
type R = ReturnType<typeof fn>;
4.5 Parameters #
获取函数参数类型:
typescript
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
function fn(a: string, b: number): void {}
type P = Parameters<typeof fn>;
4.6 InstanceType #
获取构造函数实例类型:
typescript
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
class User {
name = 'Alice';
}
type I = InstanceType<typeof User>;
五、高级应用 #
5.1 深层Partial #
typescript
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
interface User {
name: string;
address: {
city: string;
country: string;
};
}
type PartialUser = DeepPartial<User>;
const user: PartialUser = {
name: 'Alice',
address: {
city: 'NYC'
}
};
5.2 深层Required #
typescript
type DeepRequired<T> = {
[P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
};
5.3 深层Readonly #
typescript
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
5.4 函数重载类型 #
typescript
type Overload<T, U> = T extends {
(a: infer A): infer R;
(b: infer B): infer R;
} ? (a: A, b: B) => R : never;
5.5 提取数组元素 #
typescript
type ArrayElement<T> = T extends (infer E)[] ? E : never;
type A = ArrayElement<string[]>;
type B = ArrayElement<number[]>;
六、实用示例 #
6.1 类型安全的Object.keys #
typescript
type ObjectKeys<T extends object> = `${Exclude<keyof T, symbol>}`;
function getKeys<T extends object>(obj: T): ObjectKeys<T>[] {
return Object.keys(obj) as ObjectKeys<T>[];
}
const user = { name: 'Alice', age: 25 };
const keys = getKeys(user);
6.2 提取函数类型 #
typescript
type ExtractFunction<T> = T extends (...args: any[]) => any ? T : never;
type Fn = ExtractFunction<(() => void) | string>;
6.3 类型谓词 #
typescript
type IsArray<T> = T extends any[] ? true : false;
type A = IsArray<string[]>;
type B = IsArray<string>;
七、总结 #
本章介绍了TypeScript条件类型:
条件类型基础 #
- 三元运算符语法
- 条件类型分发
- infer关键字
内置条件类型 #
- Exclude
- Extract
- NonNullable
- ReturnType
- Parameters
- InstanceType
最佳实践 #
- 使用infer推断类型
- 理解分发机制
- 创建可复用的条件类型
最后更新:2026-03-26