typeScript——泛型工具和infer

一、泛型工具

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>

最后:如果有问题或不理解的地方请大家指出,谢谢大家~

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
泛在TypeScript中是一种特性,它允许我们在定义函数、接口或类时不预先指定具体的类型,而是在使用时手动指定类型。它可以帮助我们在编写可重用的代码时增加类型的安全性和灵活性。 在TypeScript中,使用尖括号(< >)来表示泛型,并在类名、函数名或接口名后面使用泛型变量来表示类型参数。例如,我们可以定义一个泛型函数来实现数组元素的反转: ```typescript function reverse<T>(array: T[]): T[] { return array.reverse(); } const numbers = [1, 2, 3, 4, 5]; const reversedNumbers = reverse(numbers); // [5, 4, 3, 2, 1] const names = ["Alice", "Bob", "Charlie"]; const reversedNames = reverse(names); // ["Charlie", "Bob", "Alice"] ``` 在上面的例子中,泛型变量`T`表示类型参数,它可以在函数体内部和函数的参数类型中使用。 除了函数,我们还可以使用泛型来定义类和接口。例如,我们可以创建一个泛型类`Box`来存储不同类型的值: ```typescript class Box<T> { private value: T; constructor(value: T) { this.value = value; } getValue(): T { return this.value; } } const numberBox = new Box<number>(42); console.log(numberBox.getValue()); // 42 const stringBox = new Box<string>("Hello"); console.log(stringBox.getValue()); // "Hello" ``` 上面的例子中,泛型变量`T`可以在类的成员变量类型、构造函数参数类型和方法返回值类型中使用。 总结来说,TypeScript泛型提供了一种灵活的方式来增加代码的可重用性和类型安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值