文章目录
一、泛型工具
1.Partial(所以属性可选)
interface User {
address: string,
name: string,
age: number
}
type PartialUser = Partial<User>
原理:keyof取interface键名并组成联合类型,in用于取联合类型的值
type CustomPartial<T> = {
[P in keyof T]?: T[P]
}
type PartialUser = CustomPartial<User>
//显示 PartialUser = {
// address?: string | undefined;
// name?: string | undefined;
// age?: number | undefined;
//}
2.Required 所以属性必选
type RequiredUser = Required<User>
//原理
type CustomPartial<T> = {
[P in keyof T]-?: T[P]
}
//显示 RequiredUser = {
// address: string,
// name: string;
// age: number;
//}
3.Pick 提取部分属性
type test = Pick<User, 'age' | 'name'> //age,name为要提取的属性
// 原理:
type Pick<T, K extends keyof T> = { [P in K]: T[P]; }
//显示 test = {
// name: string;
// age: number;
//}
4.Exclude 排除部分属性
type test = Exclude<'age' | 'name' | 'address', 'name'> //排除name,剩下name以外的
//显示 test = "age" |"address"
// 原理:为什么never就排除掉? never在联合类型中会被排除掉
type test2 = 'a' | 'b' | never
type Exclude<T, U> = T extends U ? never : T
5.Omit 排除部分属性 并且返回新的类型
type test = Omit<User, 'name'> //排除name,剩下name以外的
//显示 test = {
// address: string;
// age: number;
//}
// 原理:Exclude去排除不需要的属性,Pick提取需要的属性
type CustomOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type testq = CustomOmit<User, 'name' | 'address'> //排除name,剩下name以外的
//显示 testq = {
// age: number;
//}
6.Record
约束对象的key和value,所以接受两个泛型,第二个参数支持嵌套约束,对象的key只能时string number symbol
如果value不是规定的值则会报错
type ObjKey = keyof any //语法糖 结果为string|number|symbol
type CustomRecord<K extends ObjKey, T> = {
[P in K]: T
}
type key = 'c' | 'k' | 'h' //key不能少
type value = '唱歌' | '跳舞' | '拉姆求' //value随便
let b: Record<key, value> = {
c: '唱歌',
k: '拉姆求',
h: '跳舞'
}
let a: CustomRecord<key, CustomRecord<key, value>> = {
c: {
c: '唱歌',
k: '拉姆求',
h: '跳舞'
},
k: {
c: '唱歌',
k: '拉姆求',
h: '跳舞'
},
h: {
c: '唱歌',
k: '拉姆求',
h: '跳舞'
}
}
console.log(a, b);
7.ReturnType
获取函数类型的返回值
const fns = () => [2, 3, false]
type aarrNum = ReturnType<typeof fns>
//原理
type CustomRe<F extends Function> = F extends (...args: any[]) => infer Res ? Res : never
二、infer
1.infer 推导返回参数类型
infer只能出现在extends子语句中,infer后跟一个变量名
interface User {
name: string
age: number
}
type PromiseType = Promise<User>
type GetPromiseType<T> = T extends Promise<infer U> ? GetPromiseType<U> : T
type T = GetPromiseType<PromiseType>
//type T = User
2.infer协变
产生协变会返回联合类型
let obj = {
name: 'aaa',
age: 23
}
// type Bar<T> = T extends { name: infer N, age: infer A } ? [N, A] : T
type Bar<T> = T extends { name: infer U, age: infer U } ? U : T
type T = Bar<typeof obj>
//显示T = "string"|"number"
3.infer逆变
出现在函数的参数上面,保证参数一致性,返回交叉类型
type a = number & string //一个不能同时是number和string所以是never
type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never
type T = Bar<{ a: (x: string) => void, b: (x: string) => void }>
//显示 T = string
4.infer类型提取
type Arr = ['a', 'b', 'c']
// 提取头部元素
type First<T extends any[]> = T extends [infer one, ...any[]] ? one : []
type a = First<Arr>
// 提取尾部元素
type Last<T extends any[]> = T extends [...any[], infer last] ? last : []
type b = Last<Arr>
// 删除尾部元素
type Pop<T extends any[]> = T extends [...infer Rest, unknown] ? Rest : []
type c = Pop<Arr>
// 删除尾部元素
type Shift<T extends any[]> = T extends [unknown, ...infer Rest,] ? Rest : []
type d = Shift<Arr>
举例:
数组反转
type Arr = [1, 2, 3]
type RevvertArr<T extends any[]> = T extends [infer First, ...infer Rest] ? [...RevvertArr<Rest>, First] : T
type Arrb = RevvertArr<Arr>
最后:如果有问题或不理解的地方请大家指出,谢谢大家~