TypeScript新语法之infer extends示例详解

目录
  • 正文
    • 模式匹配
    • 提取枚举的值的类型
  • 总结

正文

我们知道,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 等类型:

试一下

总结

Typescript 支持 infer 类型,可以通过模式匹配的方式,提取一部分类型返回。

但是 infer 提取出的类型是 unknown,后面用的时候需要类似和 string 取交叉类型,或者 xxx extends string 这样的方式来转换成别的类型来用。这样比较麻烦。

所以 TS 4.7 实现了 infer extends 的语法,可以指定推导出的类型,这样简化了类型编程。

而且,infer extends 还可以用来做类型转换,比如 string 转 number、转 boolean 等。

要注意的是,4.7 的时候,推导出的只是 extends 约束的类型,比如 number、boolean,但是 4.8 就能推导出字面量类型了,比如 1、2、true、false 这种。

有了 infer extends,不但能简化类型编程,还能实现一些之前很难实现的类型转换,是很有用的一个新语法。

以上就是TypeScript新语法之infer extends示例详解的详细内容,更多关于TypeScript语法infer extends的资料请关注我们其它相关文章!

(0)

相关推荐

  • TypeScript声明文件的语法与场景详解

    目录 简介 语法 内容 模块化 模块语法 三斜线指令 reference amd-module 场景 1. 在内部项目中给内部项目写声明文件 2. 给第三方包写声明文件 全局变量的第三方库 修改全局变量的模块的第三方库的声明 修改window ESM和CommonJS UMD 模块插件 总结 简介 声明文件是以.d.ts为后缀的文件,开发者在声明文件中编写类型声明,TypeScript根据声明文件的内容进行类型检查.(注意同目录下最好不要有同名的.ts文件和.d.ts,例如lib.ts和lib.

  • 分享Typescript的13个基础语法

    目录 一.Ts是什么 二. 基本语法 1.声明原始数据类型 2.声明Object类型 2.1声明数组类型 2.2声明元组类型 3.声明枚举类型 4.函数参数与返回类型 5.任意类型 6.类型断言 7.接口基本使用 8.类基本使用 9.类的访问修饰符 10.类只读属性 11.类与接口 12.抽象类 13.泛型 一.Ts是什么 首先,强类型不允许随意的隐式类型转换,而弱类型是允许的.JavaScript就是经典的弱类型语言.而Typescript可以说是JavaScript的超集,在JS的基础上新增

  • 关于TypeScript应该尽量避免的语法总结

    目录 前言 避免枚举 避免名字空间 避免装饰器(对于现在而言) 避免 Private 关键字 总结 前言 这个文章列举了我们建议尽量避免的 TypeScript 语法.但是因为你的项目的情况,有可能使用这些特性也是合理的,但是我们仍然建议,在默认情况下,尽量避免使用这些特性. 随着时间的发展,TypeScript 已经是一门复杂的语言.在早期的时候,TypeScript 研发团队增加了一些不兼容 JavaScript 的语法.但是随着发展,新的版本已经不会这么做了,会非常保守地和严格地遵循 Ja

  • vue语法自动转typescript(解放双手)

    代码的复用是一件很常见的事情,如果是公共代码的复用那还好说,直接做成一个内部私有库,想用的话安装一下 npm包就行了,但是业务代码的复用就不好做成包了,一般都是复制粘贴 我一般写代码的时候,如果觉得某段业务代码以前见过其他人写过,那么考虑到业务优先性,只要别人的代码不是写得太烂,我一般会优先抄别人的代码,省得自己再写一遍 然后我就遇到了一个问题,公司目前前端项目大部分都是 vue,早期没有 ts这个说法,后来新项目才逐渐引入 ts,所以新项目用的是 vue-ts,而一般想抄的老代码都是没有引入

  • TypeScript中的类型断言[as语法|<>语法]的使用

    Typescript中类型断言官方解释 要理解好类型断言,其实就深刻理解一句话:你会比TypeScript更了解某个值的详细信息 . 类型断言,断言 断言,顾名思义,我断定怎么怎么样,代入这句话里就是,我断定这个类型是什么.当然这是我们主观上的思维逻辑,程序并不认可,所以我们需要告诉程序:“相信我,我知道自己在干什么” . 这么干说,大家可能还是理解的不够透彻,我用两个函数举一个例子: /** * @param d 日期 * @param f 想要格式化的字符串 */ function date

  • TypeScript新语法之infer extends示例详解

    目录 正文 模式匹配 提取枚举的值的类型 总结 正文 我们知道,TypeScript 支持 infer 来提取类型的一部分,通过模式匹配的方式. 模式匹配 比如元组类型提取最后一个元素的类型: type Last<Arr extends unknown[]> = Arr extends [...infer rest,infer Ele] ? Ele : never; 比如函数提取返回值类型: type GetReturnType<Func extends Function> = F

  • TypeScript类型断言VS类型守卫示例详解

    目录 类型断言 类型守卫 使用 in 关键字 使用 instanceof 关键字 使用 typeof 关键字 自定义类型守卫 总结 类型断言 类型断言有两种写法,分别为value as Type和<Type>value,它让 TypeScript 编译器将 value 当作 Type 类型.类型断言是一个编译时特性,不进行类型转换,因此不会影响变量在运行时的数据类型.如果某变量是 any 类型,但现在你知道它确切的数据类型,使用类型断言能让 IDE 有代码提示的能力,也能让 TypeScrip

  • TypeScript类型级别和值级别示例详解

    目录 对值级别编程类型级别编程区分 类型级编程 挑战是如何工作的 挑战 对值级别编程类型级别编程区分 首先,让我们对值级别编程和类型级别编程进行重要区分. 值级别编程让我们编写将在生产中运行的代码即运行期,并为我们的用户提供有用的东西. 类型级别编程帮助我们确保代码在发布之前即编译期不包含错误,在运行期会被完全删除 JavaScript没有类型,所以所有JavaScript都是值级别的代码: // A simple Javascript function: function sum(a, b)

  • PHP 7.4 新语法之箭头函数实例详解

    短闭包,也叫做箭头函数,是一种用 php 编写的短函数.当向函数中传递闭包时,这个功能是非常有用的,比如使用 array_map 或是 array_filter函数时. 这就是它们看起来的样子: // Post 对象的集合 $posts = [/* - */]; $ids = array_map(fn($post) => $post->id, $posts); 而以前,你必须这样写: $ids = array_map(function ($post) { return $post->id

  • 使用TypeScript实现一个类型安全的EventBus示例详解

    目录 前言 准备工作 目标 思路 具体实现 全部代码 后记 前言 随着vue3的发布,TypeScript在国内越来越流行,学习TypeScript也随即变成了大势所趋.本文就通过实现一个类型安全的EventBus来练习TypeScript,希望对小伙伴们有所帮助. 准备工作 生成一个TypeScript的基础架子: // 创建目录 mkdir ts-event-bus && cd ts-event-bus // 初始化工程 yarn init -y // 安装typescript yar

  • django模板语法学习之include示例详解

    前言 在很多网站中,基本上的都会有一个开头和一个结尾,在每一个网页中都会显示.相对于这种的来说,在Django中,最好的方法就是使用include的标签,在每一个模板中都加入这个开头和结尾的标签. include标签使用 假如我们有以下模板index.html,代码为: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>

  • Java基本语法之内部类示例详解

    目录 1.内部类概念及分类 2.实例内部类 2.1实例内部类的创建 2.2使用.this和.new 2.3内部类实现迭代打印 2.4内部类的继承 3.静态内部类 4.匿名内部类 1.内部类概念及分类 将一个类定义在另一个类的内部或者接口内部或者方法体内部,这个类就被称为内部类,我们不妨将内部类所在的类称为外围类,除了定义在类,接口,方法中的内部类,还有一种特殊的内部类,那就是使用关键字new创建一个匿名类的对象,而这个匿名类其实就是一个内部类,具体说是一个匿名内部类,经常用于传入构造器实参构造对

  • Java Stream流语法示例详解

    目录 如何使用Stream? Stream的操作分类 1.创建流 2.操作流 1)过滤 2)映射 3)匹配 4)组合 3.转换流 如何使用Stream? 聚合操作是Java 8针对集合类,使编程更为便利的方式,可以与Lambda表达式一起使用,达到更加简洁的目的. 前面例子中,对聚合操作的使用可以归结为3个部分: 1)  创建Stream:通过stream()方法,取得集合对象的数据集. 2)  Intermediate:通过一系列中间(Intermediate)方法,对数据集进行过滤.检索等数

  • TypeScript 泛型推断实现示例详解

    目录 前言 基础类型准备 最终使用的方式 基于Interface的实现 (失败了) 所有内容都基于type 实现 完整Demo 结束语 前言 最近做东西都在用ts,有时候写比较复杂的功能,如果不熟悉,类型写起来还是挺麻烦的.有这样一个功能,在这里,我们就不以我们现有的业务来举例了,我们还是已Animal举例,来说明场景.通过一个工厂来创建不同的动物实例.在这里我们借助泛型来实现类型的约束和动态推到指定类型. 基础类型准备 用一个枚举来定义Animal的类型 enum EAnimalType {

  • Typescript装饰器AOP示例详解

    目录 在Typescript中使用装饰器 配置 类装饰器 方法装饰器 AOP(面向切面编程) 在Typescript中使用装饰器 上文中讲了装饰模式,今天来来介绍一些Typescript里面的装饰器,以及如何用装饰器来实现之前提及装饰模式,装饰器只是实现装饰模式的一种方式,并非唯一 配置 在Typescript要使用装饰器需要在tsconfig打开装饰器的语法 "compilerOptions": { "experimentalDecorators": true }

随机推荐