前一篇文章我们有介绍条件类型,这篇文章我们来介绍下非常实用的infer的使用方法。

使用介绍

我们上篇文章中介绍了条件类型的基本语法是:

 T extends U ? X : Y;

如果占位符类型U是一个可以被分解成几个部分的类型,譬如数组类型,元组类型,函数类型,字符串字面量类型等。这时候可以通过infer来获取U类型中某个部分的类型。

infer语法的限制如下:

  1. infer只能在条件类型的 extends 子句中使用
  2. infer得到的类型只能在true语句中使用, 即X中使用

推断数组(或者元组)的类型

使用方法
type InferArray<T> = T extends (infer U)[] ? U : never;

(infer U)和平时常写的string[]number[]等等是不是很像?这里就是通过(infer U)来获取数组对应的类型。

案例
type I0 = InferArray<[number, string]>; // string | number
type I1 = InferArray<string[]>; // string
type I2 = InferArray<number[]>; // number

推断数组(或者元组)第一个元素的类型

使用方法
type InferFirst<T extends unknown[]> = T extends [infer P, ...infer _] ? P : never

[infer P, ... infer _]infer P获取的是第一个元素的类型,而...infer _获取的是数组其他剩余元素的数组类型;
特别说明下,我们例子汇总不需要使用其他元素的类型,所以用_

案例
type I3 = InferFirst<[3, 2, 1]>; // 3

推断数组(或者元组)最后一个元素的类型

使用方法
type InferLast<T extends unknown[]> = T extends [... infer _, infer Last] ? Last : never;

这个和推断数组第一个元素的类型类似,...infer _获取的是最后一个元素之前的所有元素类型,infer Last获取的是最后一个元素的类型。

案例
type I4 = InferLast<[3, 2, 1]>; // 1

推断函数类型的参数

使用方法
type InferParameters<T extends Function> = T extends (...args: infer R) => any ? R : never;

...args 代表的是函数参数组成的元组, infer R代表的就是推断出来的这个函数参数组成的元组的类型。

案例
type I5 = InferParameters<((arg1: string, arg2: number) => void)>; // [string, number]

推断函数类型的返回值

使用方法
type InferReturnType<T extends Function> = T extends (...args: any) => infer R ? R : never;

和前面的推断函数类型的参数类似,=> 后面的infer R代表的就是推断出来的函数的返回值类型。

案例
type I6 = InferReturnType<() => string>; // string

推断Promise成功值的类型

使用方法
type InferPromise<T> =  T extends Promise<infer U> ? U : never;
案例
type I7 = InferPromise<Promise<string>>; // string

推断字符串字面量类型的第一个字符对应的字面量类型

使用方法
type InferString<T extends string> = T extends `${infer First}${infer _}` ? First : [];
案例
type I8 = InferString<"Johnny">; // J

综合案例

接下来我举一些综合性的例子,我不介绍这些例子实现的功能,大家来感受下infer的使用技巧,看看是否能一眼看出来实现的功能:

type Shift<T> = T extends [infer L, ...infer R]? [...R] : [];
type Pop<T extends any[]> = T extends [...infer L, infer R] ? [...L] : [];
type Reverse<T extends unknown[], U extends unknown[] = []> = [] extends T? U: T extends [infer L, ...infer R]? Reverse<R, [L, ...U]>: U;
type FlipArguments<T extends Function> = T extends (...arg: infer R) => infer S ? (...arg : Reverse<[...R]>) => S : T;
type StartsWith<T extends string, U extends string> = T extends `${U}${infer R}` ? true : false;
type TrimLeft<S extends string> = S extends `${infer L}${infer R}`? L extends ' ' | '\n' | '\t'? TrimLeft<R>: S: '';
type Trim<S extends string> = S extends `${' ' | '\t' | '\n'}${infer R}`? Trim<R>: S extends `${infer L}${' ' | '\t' | '\n'}`? Trim<L>: S;
type StringToUnion<T extends string, U = never> = T extends ''? U: T extends `${infer L}${infer R}`? StringToUnion<R, U | L>: U;

这些例子中涉及到两个没有介绍的知识点:模版字面量类型递归类型,如果对这两个知识点不太懂的可以参考其他文章。这两个知识点我后面也会介绍。

TS进阶之infer相关推荐

  1. TS进阶之keyof

    刷完了type-challenges的所有简单和中等难度的题目后,对TypeScript的类型操作有了一些新的理解和认识.特此用几篇文章来记录下一些重要的知识点. 本系列文章需要您对TypeScrip ...

  2. 【TypeScript】TS进阶-函数重载(七)

  3. 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

    前端瓶子君,关注公众号 回复算法,加入前端编程面试算法每日一题群 本文知识图谱分基础.进阶和实战三个部分,分别如下: image.png image.png image.png 这三份知识图谱里罗列的 ...

  4. 「1.8W字」2020不可多得的 TS 学习指南

    阿宝哥第一次使用 TypeScript 是在 Angular 2.x 项目中,那时候 TypeScript 还没有进入大众的视野.而现在学习 TypeScript 的小伙伴越来越多了,本文阿宝哥将从 ...

  5. 写给初中级前端的高级进阶指南(万字长文,建议收藏)

    前言 由于公众号文章不允许外链,需要跳转文中链接的同学可以在脚注里找到各个的资源链接,也可以通过点击阅读原文更加方便的跳转链接. 我曾经一度很迷茫,在学了 Vue.React 的实战开发和应用以后,好 ...

  6. 写给初中级前端的高级进阶指南(万字路线)

    前言 我曾经一度很迷茫,在学了 Vue.React 的实战开发和应用以后,好像遇到了一些瓶颈,不知道该怎样继续深入下去.相信这也是很多一两年经验的前端工程师所遇到共同问题,这篇文章,笔者结合自己的一些 ...

  7. TS 类型体操还能这么玩,太秀了

    最近在看 TypeScript 相关的内容,做了一下类型体操,真的太秀啦 递归.infer 满天飞,今天就来领略一下 TS 能做什么骚操作吧! 先放上本文的几个小标题,很骚 巧用数组上数学课 模版字符 ...

  8. typescript ajax,TypeScript的应用方式

    > 本文不讲如何安装,只讲代码中的实际应用 # 一.什么是 TypeScript? typescript是js的超集,它在js的基础上增加了静态类型校验,可以在运行前校验js中的一些错误并修正. ...

  9. 入门前端学习路线图【送书】

    大家好,我是若川.记得点上方音频听小姐姐配音,超级好听. 华章图书又赞助了书籍送福利给大家.本次送4本书的抽奖方式是:截止到9月6日(周一)20:00,在留言区留言任意内容.我会在留言区抽取「1位」关 ...

  10. eltree ref什么时候有_Vue3响应式系统源码解析-Ref篇

    文章转载自:https://zhuanlan.zhihu.com/p/85978064 我们阅读源码的原因是什么?无非是1:学习:2:更好的使用这个库.如果只是想大致的了解下原理,倒不必花时间阅读源码 ...

最新文章

  1. 准备好了?测试人员迟早会被要求测试包含区块链技术的解决方案
  2. ThinkPHP5下自己写日志
  3. 6. Nginx + PHP + FastGCI安装
  4. MySQL replace into (insert into 的增强版)
  5. nextdate函数白盒测试问题 软件测试_软件测试基本常识
  6. ae制h5文字动画_AE文字拉伸动画如何制作
  7. 圣诞节插画素材|设计师再忙也要看一看,没准可以帮助到你!
  8. 放弃百万年薪,独自创业,我做错了吗?
  9. 关于 TCP window size
  10. 9.PHP核心技术与最佳实践 --- memcache
  11. Mac程序开机启动项优化
  12. autojs识别二维码
  13. java人民币数字转换中文大写(精确到人民币大写分)
  14. 三维模型重建(1):关于三维模型重建的一些简介
  15. 如何批量修改文件名、照片文件名
  16. VC++图形平移功能的实现
  17. 团队博客-第六周:Alpha阶段项目复审(科利尔拉弗队)
  18. 关键字和关键字优化(转)
  19. 基于使用方的火控系统的测试平台研究
  20. 银行家算法c语言博客,操作系统之银行家算法

热门文章

  1. 学习Java第一天笔记
  2. Excel 简单线性回归图表制作
  3. Python基础知识:切片
  4. jxd android 4.1刷机包,金星JXD V3固件
  5. containers matlab,Matlab 中实用数据结构之 containers.Map
  6. html设置成电脑桌面背景,电脑桌面背景怎么更换 电脑桌面背景不能设置怎么办...
  7. Apache Ant简介
  8. AutoIt:常用文件操作
  9. props传值强校验validator
  10. 使用VBS编写xshell/SecureCRT自动化脚本