当前位置:网站首页>TS进阶之条件类型
TS进阶之条件类型
2022-06-13 11:16:00 【JonnyLan】
前端开发者对Javascript中的三元表达式应该都很熟悉,利用三元表达式可以很方便实现根据输入值得到不同的输出结果。 TypeScript对类型也提供了类似的语法,和Javascript唯一的区别就是TypeScript操作的是数据类型。
基本语法
基本使用
T extends U ? X : Y;
TUXY四个是占位符,分别表示四种类型;T extends U表示T类型能被赋值给U类型,这里还涉及到TS类型兼容性。
几个简单的例子
- 判断类型是否是
string类型
type IsString<T> = T extends string ? true : false;
type C11 = IsString<string>; // true
type C22 = IsString<number>; // false
type C1 = IsString<"1">; // true
type C2 = IsString<1>; // false
重点:例子中的
true和false是类型(字面量类型),不是值。
- 如果是
Animal类型得到number类型,否则为string类型
interface Animal {
live(): void;
}
interface Dog extends Animal {
woof(): void;
}
type IsAnimal<T> = T extends Animal ? number : string;
type C3 = IsAnimal<Dog> // number
type C4 = IsAnimal<RegExp> // string
TS进阶之keyof中的例子
- 实现
Omit
type MyOmit<T, K> = { [P in keyof T as P extends K ? never : P]: T[P] };
- 给对象类型添加属性
type AppendToObject<T, U extends keyof any, V> = {[P in keyof T | U]: P extends keyof T ? T[P] : V}
条件类型可复合使用
例子如下:获取类型的名称
type TypeName<T> = T extends string
? 'string'
: T extends number
? 'number'
: T extends boolean
? 'boolean'
: T extends undefined
? 'undefined'
: T extends Function
? 'function'
: 'object';
这个使用方法应该也比较好理解,不过多解释了。
条件类型的分发特性
如果对条件类型的分发特性不太熟悉的同学可能会对Exclude,Extract等工具类型的实现有疑问,接下来我就使用Exclude来具体介绍下条件类型的分发特性。
重点:条件的分发特性主要针对的
T是联合类型
Exclude的具体执行逻辑
type Exclude<T, U> = T extends U ? never : T;
type C5 = Exclude<'a' | 'b' | 'c', 'a' | 'b'> // 'c'
解释:
- 对联合类型
T进行分发变成:'a' extends 'a'| 'b' ? never : 'a' | 'b' extends 'a'| 'b' ? never : 'b' | 'c' extends 'a'| 'b' ? never : 'c'
- 分别计算的结果是
never | never | 'c'- 最后的结果:
c
条件类型的分发必须是裸类型
裸类型是指没有被数组,元组和Promise等包装过的类型。
对比例子如下:
type IsString2<T> = [T] extends string[] ? "IS a String" : "Not a String";
type C7 = IsString2<string | number>;
// 结果: "Not a String"
type IsString3<T> = T extends string ? "IS a String" : "Not a String";
type C8 = IsString3<string | number>;
// 结果: "IS a String" | "Not a String"
IsString2中的[T]被数组包装过了,不会进行分发,直接判断[string | number] extends string[], 得到了"Not a String";IsString3中的[T]没被包装过,会进行分发,得到"IS a String" | "Not a String";
never是空的联合类型
如果判断一个类型是否是never,可能最开始想到的是:
type IsNever<T> = T extends never ? true : false; //
这个是错误的,因为 never代表的是空的联合类型,相当于没有,所有不会执行,最后也是never类型,不会得到true。
正确的解决逻辑是将never变成元组类型就可以了。
type IsNever<T> = [T] extends [never] ? true : false; //
一些案例
获取数组类型的第一个元素的类型
type First<T extends any[]> = T extends never[] ? never : T[0];
type arr1 = ['a', 'b', 'c']
type C6 = First<arr1> // 'a'
注意 这里的
'a','b','c',是类型,是类型,是类型;
Pick 具有某个类型的属性
type PickByType<T, U> = { [P in keyof T as T[P] extends U ? P : never]: T[P] };
type OnlyBoolean = PickByType<{
name: string
count: number
isReadonly: boolean
isEnable: boolean
}, boolean>
// 结果:
{
isReadonly: boolean;
isEnable: boolean;
}
判断Any
export type IsAny<T> = 0 extends (1 & T) ? true : false
type IsAny<T> = 0 extends (1 & T) ? true : false
type C9 = IsAny<any>; // true
type C10 = IsAny<string>; // false
解释:
any & 1 = any,0 extends any成立,所以返回true; 具体解释地址
判断两个类型完全相等
export type Equal<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false
解释:通过构造一个函数类型来对比两个函数类型是否完全相等。具体解释地址
infer
条件类型语法中可以使用infer进行类型推断,下篇主要介绍这部分内容。
先来个官方的获取参数类型的例子:
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
边栏推荐
猜你喜欢

【TcaplusDB知识库】Tmonitor单机安装指引介绍(二)

View the default MySQL password in the pagoda

17张图:读懂国内首个《主机安全能力建设指南》

服务器的使用

Vivo large scale kubernetes cluster automation operation and maintenance practice

状态压缩DP例题(旅行商问题和填矩形问题)

Web3和NFT中的匿名性问题

【TcaplusDB知识库】Tmonitor单机安装指引介绍(一)

socket编程(中)

【TcaplusDB知识库】TcaplusDB单据受理-建表审批介绍
随机推荐
2020 ICPC Asia Taiwan Online Programming Contest C Circles
阿里一季度员工减少4000人;程序员写脚本抢挂疫苗号,牟利40万被刑拘;搜狐遭遇史诗级邮件诈骗,张朝阳回应 | Q资讯
【TcaplusDB知识库】TcaplusDB单据受理-建表审批介绍
As a tester, these basic knowledge are essential
F2. nearest beautiful number (hard version)
CommonAPI与AUTOSAR AP通讯管理的异同
【TcaplusDB知识库】Tmonitor单机安装指引介绍(一)
Alibaba's employees decreased by 4000 in the first quarter; Programmers wrote scripts to hang up vaccine numbers and were arrested for making a profit of 400000 yuan; Sohu encounters epic email fraud,
2021CCPC网络赛题解加总结
Show/exec and close/hide of QT form are not executed when calling the close destructor
【TcaplusDB知识库】TcaplusDB Tmonitor模块架构介绍
面试技巧问答
Will it be a great opportunity for entrepreneurs for Tiktok to attach so much importance to live broadcast sales of takeout packages?
Log 1111
St table learning
Multithreading starts from the lockless queue of UE4 (thread safe)
socket编程(中)
Pagoda add a website: PHP project
我们用了一个周末,将 370 万行代码迁移到了 TypeScript
WinForm resolves frequent refresh of black screen