extends

extends 在TS类型编程中用法(T extends U),表示 T 中的某些在 U 里面,比较难描述,用法如下:

T extends U ? X : Y

分为两种情况理解更直观一些:

1)如果 T 不是一个联合类型,表示如果 T 是 U 的子集,那么返回 X 否则返回 Y。

举个例子,在下面的例子中,如果 T 是 U 的子集,那么返回 number,否则返回 never。

export type TExtends<T, U> = T extends U ? number : never;

// T(number)是 U(number | string)的子集,所以返回number
type TExtendsExample1 = TExtends<number, number | string>; // number // T(boolean) 不是 U(number | string)的子集,所以返回never
type TExtendsExample2 = TExtends<boolean, number | string>; // never

2)如果 T 是一个联合类型,表示如果 T 中的类型是 U 的子集,那么返回 X 否则返回 Y。这个过程可以理解为对T中的类型进行一次遍历,每个类型都执行一次 extends。

举个例子:

下面的例子中对 T 中的每个类型进行遍历,检测是否是 extends 于 null 或 undefined。如果满足这个条件就返回 never(对于联合类型来说如果返回never那就相当于不存在,因为never是所有类型的子类型),如果不满足就返回原来的类型。

type NonNullable<T> = T extends null | undefined ? never : T;

// T(number | string) 不是 U(null | undefined) 的子集,所以返回 T
type TNonNullableExample1 = NonNullable<number | string>; // number | string // T(string | null) 中 string 不是 U 的子集返回 string,null 是 U 的子集,返回 never
type TNonNullableExample2 = NonNullable<string | null>; // string

infer

infer 可以推断一个类型变量,常见用法示例:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

infer R 相当于声明一个类型变量,这个变量的类型取决于传入的泛型 T,在之前的时候 extends 右边的类型是写死的,但是在这里通过 infer R 来代替写死的类型,并且具体的类型取决于传入的泛型。

不过需要注意,R 变量只能在 true 的分支可以使用,也就是只能在 ? 的第一个分支中使用。

下面通过两个例子进行说明:

1)如果 T 是 () => infer R 的子集,那么返回 R,否则返回 number

{
type Func<T> = T extends () => infer R ? R : number; // T(string) 不是 () => infer R 的子集,因此返回 number
type TFuncExample1 = Func<string>; // number // T(() => boolean) 是 () => infer R 的子集,并且通过传入的() => boolean可以推断出 R 是 boolean,因此返回 R(boolean)
type TFuncExample2 = Func<() => boolean>; // boolean
}

2)如果 T 是 {a: infer VType, b: infer VType} 的子集,那么返回 UType | VType,否则返回number。

type TObj<T> = T extends { a: infer VType, b: infer UType} ? VType | UType : number;

// T(string)不是 {a: infer VType, b: infer UType} 的子集,因此返回 number
type TObjExample1 = TObj<string>; // number // T(string)是 {a: infer VType, b: infer UType} 的子集,因此返回 UType | VType
type TObjExample2 = TObj<{ a: number, b: string }>; // => number | string

完。

如何理解 TS 类型编程中的 extends 和 infer的更多相关文章

  1. Java EE 编程中路径

    版权声明:未经博主允许,不得转载 首先我们要限定一个范围,是一个项目,或是以个访问地址..就先以一个项目为限定的范围 前述: 学过物理学的都知道相对运动和绝对运动, 虽然是相似的概念,但这里的要简单得 ...

  2. ArcGIS 编程中对接口的理解

    学习AO,最重要的是理解“接口”这个概念.接口是什么?有什么具体作用?在多种计算机高级语言中,都可以看到“接口”这个术语,但基本上每一本书对“为什么使用接口”等重要文都都“语焉不详”,使得初学者往往不 ...

  3. 理解函数式编程中的函数组合--Monoids(二)

    使用函数式语言来建立领域模型--类型组合 理解函数式编程语言中的组合--前言(一) 理解函数式编程中的函数组合--Monoids(二) 继上篇文章引出<范畴论>之后,我准备通过几篇文章,来 ...

  4. 【Java 泛型】之 <? super T> 和<? extends T> 中 super ,extends如何理解?有何异同?

    Java 泛型 <? super T> 和<? extendsT>中 super ,extends怎么 理解?有何不同? 简介 前两篇文章介绍了泛型的基本用法.类型擦除以及泛型 ...

  5. WWDC-UIKit 中协议与值类型编程实战

    本文为 WWDC 2016 Session 419 的部分内容笔记.强烈推荐观看. 设计师来需求了 在我们的 App 中,通常需要自定义一些视图.例如下图: 我们可能会在很多地方用到右边为内容,左边有 ...

  6. Windows 编程中恼人的各种字符以及字符指针类型

    在Windows编程中,很容易见到这些数据类型:LPSTR,LPTSTR,LPCTSTR... 像很多童鞋一样,当初在学Windows编程的时候,对着些数据类型真的是丈二和尚,摸不着头脑,长时间不用就 ...

  7. Java网络编程中异步编程的理解

    目录 前言 一.异步,同步,阻塞和非阻塞的理解 二.异步编程从用户层面和框架层面不同角度的理解 用户角度的理解 框架角度的理解 三.为什么使用异步 四.理解这些能在实际中的应用 六.困惑 参考文章 前 ...

  8. Java基础 -- 深入理解Java类型信息(Class对象)与反射机制

    一 RTTI概念 认识Claa对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RT ...

  9. Java并发编程中的若干核心技术,向高手进阶!

    来源:http://www.jianshu.com/p/5f499f8212e7 引言 本文试图从一个更高的视角来总结Java语言中的并发编程内容,希望阅读完本文之后,可以收获一些内容,至少应该知道在 ...

随机推荐

  1. 【每天五分钟大数据-第一期】 伪分布式+Hadoopstreaming

    说在前面 之前一段时间想着把 LeetCode 每个专题完结之后,就开始着手大数据和算法的内容. 想来想去,还是应该穿插着一起做起来. 毕竟,如果只写一类的话,如果遇到其他方面,一定会遗漏一些重要的点 ...

  2. 初学js正则表达式之密码强度验证

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. [php代码审计] 通读审计之shangfancms

    前言 大部分的MVC框架,访问的控制器大部分是由外部参数来决定的,那么本篇文章所通读的MVC框架与之前的一系列MVC框架不太一样,它的路由是由程序本身的路由表来决定的. 源码下载 https://ww ...

  4. 【Netty】最透彻的Netty原理架构解析

    这可能是目前最透彻的Netty原理架构解析 本文基于 Netty 4.1 展开介绍相关理论模型,使用场景,基本组件.整体架构,知其然且知其所以然,希望给大家在实际开发实践.学习开源项目方面提供参考. ...

  5. Copy elision in C++

    Copy elision (or Copy omission) is a compiler optimization technique that avoids unnecessary copying ...

  6. 【Linux】【Services】【Cache】使用Sentinel搭建高可用Redis

    1. 简介 1.1. 一些基础概念请参考 http://www.cnblogs.com/demonzk/p/7453494.html 1.2. 几种常用的集群方式. -- Redis Sentinel ...

  7. 【Java 与数据库】JDBC中日期时间的处理技巧

    JDBC中日期时间的处理技巧 详谈Java.util.Date和Java.sql.Date 基础知识 Java中用类java.util.Date对日期/时间做了封装,此类提供了对年.月.日.时.分.秒 ...

  8. SOUI3界面编辑器使用说明

    SOUI一直没有官方的界面编辑器,关键是我自己一直坚持手写界面更好控制. 大概是2年前,网友"指尖"开发了一个SOUI2的编辑器,功能非常多,特点是可以拖动控件来实现可视化布局. ...

  9. MySQL常见错误总结

    一.1205 - Lock wait timeout exceeded; try restarting transaction

  10. Excel如何使用vlookup

    一.vlookup的语法 VLOOKUP (lookup_value, table_array, col_index_num, [range_lookup]) ①Lookup_value为需要在数据表 ...