内置工具类型
| 方法 | 参数类型 | 返回类型 | 描述 | 源码 |
|---|---|---|---|---|
Partial<T> | T: 对象类型 | 对象类型 | 将T中所有属性添加可选 ? | type Partial<T> = {[P in keyof T]?: T[P];} |
Required<T> | T: 对象类型 | 对象类型 | 将T中所有属性去除可选 ? | type Required<T> = {[P in keyof T]-?: T[P];}; |
Readonly<T> | T: 对象类型 | 对象类型 | 将T中所有属性添加readonly | type Readonly<T> = {readonly [P in keyof T]: T[P];}; |
Omit<T, K extends keyof any> | T: 对象类型, U: 联合类型 | 对象类型 | 从T中排除键在K中的属性 | type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>; |
Pick<T, K extends keyof T> | T: 对象类型, K: 联合类型 | 对象类型 | 从T中挑选键在K中的属性 | type Pick<T, K extends keyof T> = {[P in K]: T[P];}; |
Exclude<T, U> | T: 联合类型, U: 联合类型 | 联合类型 | 排除T在U中的类型 | type Exclude<T, U> = T extends U ? never : T; |
Extract<T, U> | T: 联合类型, U: 联合类型 | 联合类型 | 提取T在U中的类型 | type Extract<T, U> = T extends U ? T : never; |
NonNullable<T> | T: 联合类型 | 联合类型 | 排除T中的undefined和null类型 | type NonNullable<T> = T & {}; |
Parameters<T extends (...args: any) => any> | T: 函数类型 | 元组类型,内容根据范型决定 | 返回函数所有参数的类型的元组 | type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never; |
ReturnType<T extends (...args: any) => any> | T: 函数类型 | 根据范型决定 | 返回函数返回值的类型 | type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any; |
类型的方法
[P in K]: T
[P in K]: T类似于for...in,表达式返回对象类型
K是一个联合类型,P是从K迭代出来的, T为对象中值的类型
// K从联合类型'x' | 'y'中迭代,值的类型为number
type Coord = {
[K in 'x' | 'y']: number;
};
// 得到
type Coord = {
x: number;
y: number;
}
// K从联合类型'x' | 'y'中迭代,值的类型为K
type Coord = {
[K in 'x' | 'y']: K
};
// 得到
type Coord = {
x: 'x';
y: 'y';
}
利用映射类型进行复制
// 定义类型item
type Item = {
a: string
b: number
c: boolean
}
// 定义类型ItemKeys
type ItemKeys = 'a' | 'b' | 'c';
// K从ItemKeys中迭代,值的类型为Item中对应K的类型
type Copy = {
[K in ItemKeys]: Item[K]
};
// 得到
type Copy = {
a: string,
b: number,
c: boolean
};
keyof
返回对象类型中的所有key的联合类型
type Item = {
a: string
b: number
c: boolean
}
type ItemKeys = keyof Item; // 返回 'a'|'b'|'c'
// 优化一下Copy
type Copy = {
[K in keyof Item]: Item[K]
};
// 得到
type Copy = {
a: string,
b: number,
c: boolean
};
特殊:keyof any 返回 string | number | symbol
extends
约束范型的范围
// 内置类型Record的源码
// keyof any返回联合类型 string | number | symbol
// extends 约束范性K在联合类型keyof any中
type Record<K extends keyof any, T> = {
[P in K]: T;
};
使用
// Record 第一个范性必须属于string | number | symbol
const userInfo: Record<string, string|number> = {
name: 'yxx',
age: 18
}
infer
infer 推导泛型中某个属性的类型 infer 只能在 extends 的右边使用,infer P 的 P 也只能在条件类型为 True 的一边使用
// ReturnType 返回函数类型的返回值类型
// 1. 约束T为函数类型,
// 2. T extends (...args: any) => infer R 表示要推导函数的返回值类型
// 3. R就代表T的反回值类型,最后把R返回
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
// 使用
type Func = ()=>string
let name: ReturnType<Func> = '得到Func返回值类型为string'
// Parameters返回一个元组类型,内容为函数参数类型的集合
// 约束T为函数类型,推导把函数参数的类型,即P为函数参数类型构成的元组类型,最后返回P
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
// 使用
type Func = (name: string, age: number)=>void
let name: ReturnType<Func> = ['sss', 100] // ReturnType<Func>表达式得到类型 [string, number]
// 把范型T约束在{data: any}中,推导data的类型,R就是T中data的类型,最后返回R
type DataType<T extends {data: any}> = T extends {data: inter R} ? R : any;
type Info = {
data: string
}
let data: DataType<Info> = '得到Info中data的类型为string'
readonly / ? / + / -
readonly 将属性设为只读 ? 将属性设为可选
type Coord = {
readonly [K in 'x' | 'y']: number
};
// 得到
type Coord = {
readonly x: number;
readonly y: number;
};
// 两个装饰符也可组合使用:
type Coord = {
readonly [K in 'x' | 'y']?: number;
};
// 得到
type Coord = {
readonly x?: number;
readonly y?: number;
};
// 但这里面也有局限性,无法去除属性上已经存在的 装饰符:
type CoordOptional = {
x?: number;
readonly y: number;
};
type Coord = {
[K in keyof CoordOptional]: number;
};
// 得到
type Coord = {
x?: number;
readonly y: number;
};
因为这个原因,社区又在 TS2.8 又对其进行了完善,可以在上面的装饰符添加 - 或 + 符号:
type CoordOptional = {
x?: number;
readonly y: number;
};
type Coord = {
-readonly [K in keyof CoordOptional] -?: number;
};
// 得到
type Coord = {
x: number;
y: number;
};
向interfaces中添加任意属性
我们使用interfaces定义对象时,有哪些属性,是什么类型都是一一定义好了,如果我们想要向对象中添加任意属性时就可以使用 [key:string] 来定义
// tableColumnList的项
export interfaces Column {
prop: string,
label: string,
//自定义key 任意值
[key:string]: unknown,
}
const column: Column = {
prop: 'name',
label: '姓名',
// 添加任意类型
myData: 'test1'
}
as const
使用readonly、const定义对象或数组类型时只能限制变量不能直接被修改,但我们仍可以修改深层的属性 用as const来声明,可以确保所有属性都不能被修改
const list = [1,2,3]
list[0] = 100 // 可以修改
const list = [1,2,3] as const
list[0] = 100 // 不能修改
将数组转换成类型
当我们有一个数组,想定义一个该数组内容的联合类型时,使用下面这个方法
const arr = ['name', 'age', 'location', 'email'] as const;
type A = typeof arr[number];
// 得到联合类型
type A = 'name'|'age'|'location'|'email'