【ts】typescript高阶:条件类型与infer

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前端必备工具推荐网站(免费图床、API和ChatAI等实用工具):
http://luckycola.com.cn/

前言

学习目标
1、学习ts中的条件类型extends
2、infer用于存储类型推断出的类型
3、UnpackedArray、UnpackedFn、Unpacked、PropertyType、UnionToIntersection工具类型的实现


提示:以下是本篇文章正文内容,下面案例可供参考

一、s中的条件类型extends

1、条件类型的语法

// 条件类型(其中extends可以理解为T类型(窄类型)是否是U类型(宽类型)的子类型,或者说T类型是否可以赋值给U类型,语法同js的三元表达式)
T extends U ? U : T;

2、infer的使用

  1. infer只能在extends类型语句中使用
  2. infer存储的变量U只能用于语句的true返回分支
// 
type UnpackedArray<T> = T extends (infer U)[] ? U : T;

3、infer的新特性

  1. infer在推断元组类型使用中可以简写
// 不简写
type FirstString<T> = T extends [infer R, ...unknown[]] ? R extends string ? R : never : never;

// 简写
type FirstStringE<T> = T extends [infer R extends string, ...unknown[]] ? R : never;

type A = FirstString<[string, number, boolean]>; // string
type B = FirstString<['hello', number, boolean]>; // 'hello'
type C = FirstString<['hello' | 'word', number, boolean]>; // 'hello' | 'word'
type H = FirstString<[number, boolean]>; // never

二、工具类型的实现

1.UnpackedArray

功能:获取数组类型的值类型

代码如下(示例):

type Arr = string[];
// 工具类型
type UnpackedArray<T> = T extends (infer R)[]R : T;

type newArr = UnpackedArray<Arr>; // string

2.UnpackedFn

功能:获取函数返回值类型

代码如下(示例):

type fn = (x: boolean) => number;
// 函数重载工具类型将取最后一个函数的定义
declare function foo(x: number): number;
declare function foo(x: string): string;
declare function foo(x: string | number): string | number;

// 工具类型
type UnpackedFn<T> = T extends (...ags: any[]) => (infer R) ? R : T;
type Fn2 = UnpackedFn<typeof foo>;// string | number
type Fn3 = UnpackedFn<fn>; // number

3.PropertyType

功能:获取对象类型的key类型

代码如下(示例):

type User = {
	name: string;
	age: number;
};
// 工具类型
type PropertyType<T> = T extends {name: infer R; age: infer U} ? [R, U] : T;
type Pro1 = PropertyType<User>; // [string, number]

逆变位置交叉类型

type User = {
	a: (x: string) => void;
	b: (x: number) => void;
};
// 工具类型
// 注意:这里是逆变位置应该参数R存多个值 取交叉类型运算
type PropertyType<T> = T extends {a: (x: infer R) => void; b: (x: infer R) => void} ? R: T;
type Pro1 = PropertyType<User>; // string & number ⇒ nerver

协变位置联合类型

type User = {
	a: string;
	b: number;
};
// 工具类型
// 注意:这里是协变位置应该参数R存多个值 取联合类型运算
type PropertyType<T> = T extends {a: infer R; b: infer R} ? R: T;
type Pro1 = PropertyType<User>; // string | number

4.UnionToIntersection

联合类型转交叉类型(原理就是利用infer逆变位置的特性)
ts是分布式类型分支匹配模式

type union = { a: 'a'} | {b: 'b'};
// 工具类型
type UnionToIntersection<T> = (T extends any ? (ags: T=> void : never) extends (ags: infer R) => void ? R : never;

type Intersection = UnionToIntersection<union>;// {a: 'a'} & {b: 'b'}

5.Unpacked

通用获取类型的工具类型

// 工具类型
// 条件列
type UnPacked<T> = T extends (infer U)[] ? U : T extends (...ags: any[]) => infer R ? R : T extends Promise<infer U> ? U : T;
// 使用
type T0 = UnPacked<string>; // string
type T1 = UnPacked<string[]>; // string
type T3 = UnPacked<() => Number>; // Number
type T4 = UnPacked<Promise<string>>; // string
type T5 = UnPacked<UnPacked<Promise<string>>>; // string

总结

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LuckyCola2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值