TypeScript 类型工具
对象和对象类型
对象(Object) 和 对象类型(Object Type) 在 TypeScript 中有本质区别,且分别属于 值空间(Value Space) 和 类型空间(Type Space)。
keyof
关键字 keyof
是 TypeScript 特有的关键字。获取对象类型所有键的联合类型,常用于类型安全访问属性。
typeof
关键字 typeof
在 TypeScript 中用于将对象转为对象类型。推导变量或表达式的静态类型,常用于类型复用。
条件类型
type AAA = { name: string; age: number };
type BBB = { name: string };
type CCC = BBB extends AAA ? true : false; //false
检查类型 BBB 是否可以赋值给类型 AAA(即 BBB 是否是 AAA 的子类型,或结构兼容)。
type AAA = string | boolean | number;
type BBB = string | number;
type CCC = BBB extends AAA ? true : false; //true | false
type CCC = [BBB] extends [AAA] ? true : false; //false
BBB extends AAA ? true : false:
这是直接的条件类型判断,当BBB
是联合类型时,会进行分布式条件类型判断。[BBB] extends [AAA] ? true : false:
这里使用了包裹类型[BBB]
,这会阻止分布式条件类型。
Exclude
,从 AAA(联合类型)中删除 BBB(联合类型)
type EXCLUDE<T, U> = T extends U ? never : T;
type AAA = string | number;
type BBB = string;
const XXX: EXCLUDE<AAA, BBB> = 100;
const YYY: Exclude<AAA, BBB> = 100;
Extract
,从 AAA(联合类型)中保留 BBB(联合类型)
type EXTRACT<T, U> = T extends U ? T : never;
type AAA = string | number;
type BBB = number | boolean;
const XXX: EXTRACT<AAA, BBB> = 100;
const YYY: Extract<AAA, BBB> = 100;
Pick
,从 AAA(对象类型) 中挑选出 BBB(联合类型)组成新的类型
type PICK<T, U extends keyof T> = { [P in U]: T[P] };
type AAA = { name: string; age: number; skill: string };
const XXX: PICK<AAA, 'name' | 'age'> = { name: 'Alrcly', age: 18 };
const YYY: Pick<AAA, 'name' | 'age'> = { name: 'Alrcly', age: 18 };
TypeScript 的映射类型
语法是 [P in U]: T[P]
这种
extends
的作用取决于它所处的上下文
关键字 条件类型判断:当 extends 出现在类型定义的条件部分时,它用于条件类型判断。形式是T extends U ? X : Y
。这种情况下,它会检查类型 T 是否可以赋值给类型 U(即 T 是否是 U 的子类型)。如果可以,则类型为 X,否则类型为 Y。
泛型约束:当 extends 出现在泛型类型定义中时,它用于约束泛型的类型。形式是 <T extends U>
。这种情况下,它表示泛型类型 T 必须是类型 U 或 U 的子类型。这可以限制泛型可以接受的类型范围,并允许在泛型类型中使用特定于该类型的属性或方法。
Omit
,从 AAA(对象类型) 中过滤掉 BBB(联合类型)组成新的类型
type OMIT<T, U> = Pick<T, { [K in keyof T]: K extends U ? never : K }[keyof T]>;
type AAA = { name: string; age: number; city: string };
type xxx = OMIT<AAA, 'name' | 'age'>;
type YYY = Omit<AAA, 'name' | 'age'>;
关键的中间形态,这个中间形态是 对象类型 而不是 对象 。
{"a": never; "b": never; "c": "c"}["a" | "b" | "c"]
== {对象类型}[联合类型]
当通过 ["a" | "b" | "c"] 访问对象类型的属性时,TypeScript 会将所有键对应的属性类型进行联合。
Partial
,用于将 AAA (对象类型) 的全部属性设置为可选
type PARTIAL<T> = { [P in keyof T]?: T[P] };
type AAA = { name: string; age: number };
const XXX: PARTIAL<AAA> = { name: 'Alrcly' };
const YYY: Partial<AAA> = { name: 'Alrcly' };
Record
,用于快速定义 AAA (对象类型) 的对象类型
type RECORD<K extends string | number | symbol, V> = { [P in K]: V };
type XXX = RECORD<'name' | 'age', string | number>;
type XX = {
name: string | number;
age: string | number;
};
type YYY = Record<string, number>;
type YY = {
[x: string]: number;
};
TypeScript 中的索引签名
type AAA = {
[x: string]: string;
};
let AA: AAA = {
aaa: 'aaa',
bbb: 'bbb',
ccc: 'ccc',
};
交叉类型在 Typescript 中的使用
将 AAA(对象类型) 和 BBB(对象类型)组成新的对象类型
type AAA = { name: string };
type BBB = { age: number; name: string };
type CCC = AAA & Pick<BBB, 'age'>;
let CC: CCC = { age: 30, name: 'Alrcly' };