TypeScript 的类型系统是一门图灵完备的语言:它支持条件分支、循环(递归)、变量声明(泛型),可以表达极其复杂的类型关系。本文从实用角度讲解高级类型,提供可直接复用的类型工具。
一、条件类型(Conditional Types)
type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<42>; // false
infer 关键字(类型提取)
// 提取 Promise 的返回值类型
type Awaited<T> = T extends Promise<infer R> ? R : T;
type Result = Awaited<Promise<string>>; // string
// 提取函数返回类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Fn = () => number;
type R = ReturnType<Fn>; // number
// 提取数组元素类型
type ElementType<T> = T extends Array<infer E> ? E : never;
type E = ElementType<string[]>; // string
二、映射类型(Mapped Types)
// 把所有属性变为可选
type Partial<T> = {
[K in keyof T]?: T[K];
};
// 把所有属性变为只读
type Readonly<T> = {
readonly [K in keyof T]: T[K];
};
// 只保留指定属性
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
// 自定义:把对象的所有值转为 string
type Stringify<T> = {
[K in keyof T]: string;
};
interface User {
name: string;
age: number;
}
type StringUser = Stringify<User>;
// { name: string; age: string; }
三、模板字面量类型
type EventName<T extends string> = `on${Capitalize<T>}`;
type ClickEvent = EventName<'click'>; // 'onClick'
// 生成 CSS margin/padding 工具类类型
type Spacing = 'xs' | 'sm' | 'md' | 'lg';
type MarginClass = `m-${Spacing}` | `mx-${Spacing}` | `my-${Spacing}`;
// 'm-xs' | 'm-sm' | 'mx-xs' | 'mx-sm' | ...
四、实用类型工具集
// 1. DeepPartial — 递归可选
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
// 2. RequiredBy — 只让部分属性必填
type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
// 3. NonNullableProperties — 移除所有 null/undefined
type NonNullableProperties<T> = {
[K in keyof T]: NonNullable<T[K]>;
};
// 4. Flatten — 拍平嵌套对象
type Flatten<T> = T extends object ? { [K in keyof T]: T[K] } : T;
// 5. UnionToIntersection — 联合转交叉
type UnionToIntersection<U> = (
U extends any ? (k: U) => void : never
) extends (k: infer I) => void ? I : never;
相关阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。