当前位置: 首页 > news >正文

ts:条件类型

1. 条件类型表达式 T extends U ? X : Y

基本语法: T extends U ? X : Y
(T 和 U 是类型,而 X 和 Y 是类型或者类型表达式。)

用于判断 T的每个成员 是否是 U 的子类型。如果是,则返回 X,否则返回 Y。最终返回多个Y 联合的结果(never在联合类型中会被忽略)

1. 基本用法--判断类型
// 判断是不是字符串
type IsString<T> = T extends string ? true : false;
type Result1 = IsString<string>;      // true  
//判断是不是数组
type isArray<T> = T extends Array<any> ? true : false
type testArray = isArray<'123'>
判断是不是对象
type isObject<T> T extends object > true : false
type testObject = isObject<{a:'123'}>
// 判断是不是never类型
// T extends never,再ts中never 是所有类型的子类型,因此,T extends never 几乎总是 false
//(除非 T 就是 never 类型),这个条件在类型推断和类型守卫中并不常用。
type IsNever<T> = [T] extends [never] ? true : false
type IsNever1 = IsNever<never> // true
type IsNever2 = IsNever<'a' | 'b'> // false
2. 提取元组的类型
type ArrayElementType<T extends any[]> = T extends (infer U)[] ? U : never;  
// 使用示例  
const numbers: number[] = [1, 2, 3];  
type NumberElementType = ArrayElementType<typeof numbers>; // number  
3. 排除null或undefined的类型
type noNull<T> = T extends null | undefined ? never : T
type Result1 = noNull<string | null>
4. 递归条件类型示例
type DeepArrayElementType<T> =  T extends any[]  ? T[number] extends infer U  ? U extends any[]  ? DeepArrayElementType<U>  : U  : never  : T;  // 使用通用版本  
type Example5 = DeepArrayElementType<number[][][]>; // number  
type Example6 = DeepArrayElementType<string | number[][]>; // string | number
6. 条件烈类型与泛型类型结合使用

条件表达式可以实现递归

// 1. 只针对接口的递归
//实现一个泛型 DeepReadonly<T>,它将对象的每个参数及其子对象递归地设为只读。
type X = {x: {a: 1;b: "hi";};y: "hey";
};type Expected = {readonly x: {readonly a: 1;readonly b: "hi";};readonly y: "hey";
};type DeepReadonly<T> = {readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};let zs: DeepReadonly<X> = {x: {a: 1,b: "hi",},y: "hey",
};
zs.x.b = "xc";
2. 递归元组

infer

infer 关键字用于在泛型条件类型中推断类型。它允许你声明一个类型变量,该变量会在条件类型被解析时自动推断出具体的类型。

infer 关键字通常与条件类型和映射类型中的 extends 关键字一起使用,但是,infer 并不一定要与 extends 结合使用。
infer 可以在一个条件类型中多次使用,以捕获不同的类型信息。

1. 提取数组元素类型
type ElementType<T extends any[]> = T extends (infer U)[] ? U : never;  
// 使用示例  
type NumArrayElementType = ElementType<[1, 2, 3, 4]>; // number  
type MixedArrayElementType = ElementType<[1, "two", true]>; // number | "two" | true,但通常这不是我们想要的
2. 提取数组最后一个元素类型
type arr1 = [1, 2, 3]
type FirstElement<T extends any[]> =  T extends [...infer First, infer Rest] ? Rest : never;  
type lastTest  = FirstElement<arr1>
3. 提取数组第一个元素类型
type arr2 = ['a', 'b', 'c']
type FirstElement<T extends any[]> =  T extends [infer First, ...infer Rest] ? First : never;  
type firstTest  = FirstElement<arr1>
4. 提取函数参数类型
type FunctionParams<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;  
type Params = FunctionParams<(a: string, b: number) => void>; 
5. 提取对象属性值类型
type ValueTypeOfProperty<T, K extends keyof T> = T[K] extends (infer V) ? V : never;  
type Obj = {  a: string;  b: number;  
};  
type AType = ValueTypeOfProperty<Obj, 'a'>;  
// AType 类型为 string   
6. 提取函数返回类型
type FunctionReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never;  
type ReturnType = FunctionReturnType<() => string>;  
// ReturnType 类型为 string
7. 提取联合类型中的各个类型
8. 创建类型变换(如数组转换成元组)

2. Exclude

Exclude<T, U>用于从类型 T 中排除所有可分配给类型 U 的成员。

type T0 = Exclude<"a" | "b" | "c", "a" | "b">;  // "c"  
type T2 = Exclude<string | number | (() => void), Function>;  // string | number

3. Uppercase

ts的 内置条件类型,用于将字符转成大写

type Greeting = "hello";  
type UppercaseGreeting = Uppercase<Greeting>; // 类型为 "HELLO"  

相关文章:

  • MySQL:如果用left join的话,左边的表一定是驱动表吗
  • Diffusion Policy:基于扩散模型的机器人动作生成策略
  • CLIP源码详解:clip.py 文件
  • 【除了知乎,大家都在逛什么?持续更新~~】
  • python数据分析——apply 1
  • 全局查询筛选器适用场景 以及各场景示例
  • 算法刷题day54:搜索(一)
  • Alamofire常见GET/POST等请求方式的使用,响应直接为json
  • HQL面试题练习 —— 取出累计值与1000差值最小的记录
  • 链表经典题目—相交链表和链表倒数第k个节点
  • 基于香橙派 Ai Pro的ROS Qt人机交互软件部署指南
  • 漫步者x1穷鬼耳机双耳断连
  • idea配置ssh、sftp连接服务器,docker插件使用,极其方便,无需再开第三方软件去操作服务器了,集成用于Idea一体
  • 【Java继承】(超级详细!!!)
  • 【pm2 - sdk 集成到程序中,典型用法】
  • C语言笔记(第一章:C语言编程)
  • docker python 配置
  • in typeof instanceof ===这些运算符有什么作用
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JSDuck 与 AngularJS 融合技巧
  • JS数组方法汇总
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • node入门
  • Node项目之评分系统(二)- 数据库设计
  • Promise初体验
  • python 学习笔记 - Queue Pipes,进程间通讯
  • python学习笔记-类对象的信息
  • spring security oauth2 password授权模式
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • Unix命令
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 如何设计一个比特币钱包服务
  • RDS-Mysql 物理备份恢复到本地数据库上
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 交换综合实验一
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​如何防止网络攻击?
  • # 数据结构
  • (BAT向)Java岗常问高频面试汇总:MyBatis 微服务 Spring 分布式 MySQL等(1)
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (算法)Travel Information Center
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .NET8 动态添加定时任务(CRON Expression, Whatever)
  • .NET处理HTTP请求
  • .NET企业级应用架构设计系列之应用服务器
  • .NET学习教程二——.net基础定义+VS常用设置
  • [22]. 括号生成
  • [AIGC] 使用Curl进行网络请求的常见用法