TypeScript新语法之infer extends示例详解
作者:zxg_神说要有光 发布时间:2024-03-13 20:42:27
我们知道,TypeScript 支持 infer 来提取类型的一部分,通过模式匹配的方式。
模式匹配
比如元组类型提取最后一个元素的类型:
type Last<Arr extends unknown[]> =
Arr extends [...infer rest,infer Ele]
? Ele
: never;
比如函数提取返回值类型:
type GetReturnType<Func extends Function> =
Func extends (...args: any[]) => infer ReturnType
? ReturnType
: never;
比如字符串提取一部分,然后替换:
type ReplaceStr<
Str extends string,
From extends string,
To extends string
> = Str extends `${infer Prefix}${From}${infer Suffix}`
? `${Prefix}${To}${Suffix}` : Str;
模式匹配就是通过一个类型匹配一个模式类型,需要提取的部分通过 infer 声明一个局部变量,这样就能从局部变量里拿到提取的类型。
infer 的模式匹配用法还是挺好理解的。
但是 infer 有一个问题,比如这样:
从 string 数组中提取的元素,默认会推导为 unknown 类型,这就导致了不能直接把它当 string 用:
那怎么办呢?
之前的处理方式是这样的:
加一层判断,这样 Last 就推导为 string 类型了。
或者也可以和 string 取交叉类型:
这样也可以作为 string 来用。
但是我们明明知道这里就是 string,却还需要 & string 或者 xxx extends string 来转换一次,这也太麻烦了。
TS 也知道有这个问题,所以在 4.7 就引入了新语法:infer extends。
现在我们可以这样写:
infer 的时候加上 extends 来约束推导的类型,这样推导出的就不再是 unknown 了,而是约束的类型。
试一下
这个语法是 TS 4.7 引入的,在 4.8 又完善了一下。
比如这样一个类型:
type NumInfer<Str> =
Str extends `${infer Num extends number}`
? Num
: never;
在 4.7 的时候推导结果是这样:
而 4.8 就是这样了:
也就是说 4.7 的时候推导出的就是 extends 约束的类型,但是 4.8 的时候,如果是基础类型,会推导出字面量类型。
有了这个语法之后,除了能简化类型编程的逻辑之外,也能实现一些之前实现不了的功能:
提取枚举的值的类型
enum Code {
a = 111,
b = 222,
c = "abc"
}
我们都是这样写:
但是有的值明明是数字,却被作为了字符串,所以要再处理一下,转换成数字类型,这时候就可以用 infer extends 了:
type StrToNum<Str> =
Str extends `${infer Num extends number}`
? Num
: Str
做完 string 到 number 的转换,就拿到了我们想要的结果:
这就是 infer extends 的第二个作用。
处理 string 转 number 之外,也可以转 boolean、null 等类型:
试一下
来源:https://juejin.cn/post/7133438765317488677


猜你喜欢
- Chrome的CSS支持程度 :Green / √ means current support.Orange / Δ means that
- 1. show variables like '%profiling%';(查看profiling信息) &nbs
- 代码如下:using System; using System.Data; using System.Configuration; usin
- 一、数据库备份种类按照数据库大小备份,有四种类型,分别应用于不同场合,下面简要介绍一下:1.1完全备份这是大多数人常用的方式,它可以备份整个
- 本文为大家分享了pygame游戏之旅的第5篇,供大家参考,具体内容如下在游戏中添加显示文字:这里自己定义一个crash函数接口:def cr
- 本文实例讲述了python实现在控制台输入密码不显示的方法。分享给大家供大家参考。具体实现方法如下:import console;names
- 我就废话不多说了,大家还是看代码吧! import PyPDF2 import repdf_file = open('xxx.pdf
- kafka的认证方式一般有如下3种:1.SASL/GSSAPI 从版本0.9.0.0开始支持2.SASL/PLAIN 从版本0.10.0.0
- 1、解决方案mysql是不支持跨库连接的,如果我们实在要连接的话可以用dblink方式。解释:dblink就是我们在创建表的时候连接到我们的
- 直接上代码import pygameimport randomdef main(): # 初始化pygame &n
- 在正文开始之前,先了解vue基于源码构建的两个版本,一个是 runtime only ,另一个是 runtime加compiler 的版本,
- 如下所示:"""提取文档数超过10000的数据按照某个字段的值具有唯一性进行升序,按照@timestamp进行
- 本文实例讲述了PHP实现无限极分类的两种方式。分享给大家供大家参考,具体如下:面试的时候被问到无限极分类的设计和实现,比较常见的做法是在建表
- 最近在网上经常看到朋友们聊到UEO,我就想哈UEO是啥东西啊,我去找啦些资料看,他们都说将来UEO发展一定会比较好,我也说这是肯定的.我为什
- 前言上个篇章中我们主要介绍了OpenTelemetry的客户端的一些数据生成方式,但是客户端的数据最终还是要发送到服务端来进行统一的采集整合
- 正文开始if name == "main":可以看成是python程序的入口,就像java中的main()方法,但不完全
- 1. 准备工作首先编写getHtml函数,传入markdown文本字符串,这里使用fs读取markdown文件内容,返回值是转换过后的字符串
- python pyinstaller pyqt4 打包 QWindows最近在做课设,用pyqt设计界面。然后用pyinstaller打包程
- __new__: 对象的创建,是一个静态方法,第一个参数是cls。(想想也是,不可能是self,对象还没创建,哪来的self)__init_
- 有时候要用Javascript输常用的字符,比如每个页面都要有的脚注。这里提供一个转换脚本:将HTML自动转为JS代码<script&