typeof – 对象
一般我们都是先定义类型,再定义变量,使用typeof可以得到变量的类型。
const options = {
a: 1
}
type Options = typeof options
keyof – 枚举类型(可以理解为keyof 对象类型)
首先来看keyof的定义:keyof操作符可以用来枚举出一个对象中的所有key值。
通俗来说,keyof可以取出一个对象中的所有由key值组成的枚举类型。
interface Person {
name: string;
age: number;
}
type K1 = keyof Person; // "name" | "age"
type K2 = keyof Person[]; // "length" | "toString" | "pop" | "push" | "concat" | "join"
type K3 = keyof { [x: string]: Person }; // string | number




可以看到使用let a: { [key in keyof Person]: string };可以看到keyof Person返回的枚举类型。
in – 枚举类型
in的定义是:用于遍历枚举类型。
注意:in只能遍历枚举类型,不能遍历对象(keyof遍历的是对象(类型))。
故而,Partial(type Partial<T> = { [P in keyof T]?: T[P] };)中,使用的是keyof,若是改成[P in T]?: T[P]则会报错,因为由T[P]得知,T为对象,而由[P] in T得知,T只能为string | number | symbol,故而有冲突。
再看下面这个例子:
export enum IFlag {
A = 'A',
B = 'B',
C = "C",
D = "D",
}
export const OFlag: {[key in IFlag]?: string} = {
[IFlag.A]: '情景A',
[IFlag.B]: '情景B',
[IFlag.C]: '情景C',
[IFlag.D]: '情景D',
}
在项目中,使用此方式来管理页面中一些固定的键值,例如select下拉选项:
<select>
<option value="A">情景A</option>
<option value="B">情景B</option>
<option value="C">情景C</option>
<option value="D">情景D</option>
</select>
IFlag枚举出所有的值,作为接口的入参,OFlag配置页面的文案展示。
注意:IFlag需定义为字符串枚举。
Partial – 对象类型
Partial实现源码node_modules/typescript/lib/lib.es5.d.ts
type Partial<T> = { [P in keyof T]?: T[P] };
使用keyof T拿到T中的所有的属性值,[P in keyof T]表示P在keyof T内,T[P]取出对应属性的值,?代表属性可选。
Required --对象类型
Required实现源码node_modules/typescript/lib/lib.es5.d.ts。
type Required<T> = { [P in keyof T]-?: T[P] };
-?的作用就是把可选属性的可选性去掉,使该属性变成必选项,对应的还有+?(等价于?),作用与-?相反,是把属性变为可选项。
[P in keyof T]?: T[P]:可选[P in keyof T]+?: T[P]:可选,等价于?[P in keyof T]-?: T[P]:必选[P in keyof T]: T[P]:可选的依然可选,必选的依然必选
Exclude<T, U> – 枚举类型
从T中去除T与U的交集后的类型。Exclude实现源码node_modules/typescript/lib/lib.es5.d.ts。
type Exclude<T, U> = T extends U ? never : T;
例子:
type T = Exclude<1 | 2 | 3 | 4 | 5, 3 | 4>
Extract<T, U> – 枚举类型
从T中提取T与U的交集类型。Extract实现源码node_modules/typescript/lib/lib.es5.d.ts。
type Extract<T, U> = T extends U ? T : never;
例子:
type T = Extract<1 | 2 | 3 | 4 | 5, 3 | 4> // T = 3 | 4
Pick<T, K> – 对象类型
从T中提取出T与K属性值相同的属性。Pick实现源码node_modules/typescript/lib/lib.es5.d.ts。
Pick与Extract都有从T中提取T与K相交的那部分,他们的区别在于Pick作用于对象类型,返回的类型用于定义对象;Extract作用于枚举类型,返回的类型用于定义枚举类型变量。
type Pick<T, K extends keyof T> = { [P in K]: T[P]; };
例子:假设Person类型中有name、age、sex属性,当我们想生成一个新的类型只支持name、age时,则可使用Pick:
interface Person {
name: string,
age: number,
sex: string,
}
let person: Pick<Person, 'name' | 'age'> = {
name: '小王',
age: 21,
}
Omit<T, K>(非内置)
从对象T中剔除key为K中的属性。
Omit在TS中没有内置,Omit可以使用Pick和Exclude实现。
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
例子:
剔除Person中的name属性。
interface Person {
name: string,
age: number,
sex: string,
}
let person: Omit<Person, 'name'> = {
age: 18,
sex: '男'
}
Record<K, T>
将K中所有的属性的值的类型转化为T类型。Record实现源码node_modules/typescript/lib/lib.es5.d.ts。
type Record<K extends keyof any, T> = { [P in K]: T; };
例子:
将Person中的属性值的类型全部转为string类型。
interface Person {
name: string,
age: number,
}
let person: Record<keyof Person, string> = {
name: '小王',
age: '12',
}
NonNullable<T> – 枚举类型
剔除T为null、undefined的类型。NonNullable实现源码node_modules/typescript/lib/lib.es5.d.ts。
type NonNullable<T> = T extends null | undefined ? never : T;
例子:
type T = NonNullable<string | string[] | null | undefined>; // string | string[]
ReturnType<T>
获取函数T返回值的类型。ReturnType实现源码node_modules/typescript/lib/lib.es5.d.ts。
type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
infer R相当于声明一个变量,接收传入函数的返回值类型。
例子:
type T1 = ReturnType<() => string>; // string
type T2 = ReturnType<(s: string) => void>; // void
Conditional Types(条件类型)
条件类型测试两种类型,然后根据该测试的结果选择其中一种。表现形式为T extends U ? X : Y, 即如果类型T是类型U的子类型,则返回X类型,否则返回Y类型。
type NonNullable<T> = T extends null | undefined ? never : T;
通过一个简单的案例来进行理解,当泛型T为string类型的时候,那么B为type B = "1",反之为type B = "2"。可以看到同样的一个类型,因为传入的泛型T不一样,结果自然而然的有了出入。
type B<T> = T extends string ? '1' : '2';
const a: B<string> = '1';
const b: B<number> = '1'; // 不能将类型"1"分配给类型"2"
掘金迁移到CSDN
5261

被折叠的 条评论
为什么被折叠?



