在线客服

TypeScript 的 extends 条件类型

adminadmin 报建百科 2024-04-25 105 12
TypeScript 的 extends 条件类型

这是 TS2.8 版本中推出的特性,此能力让类型定义变的更加灵活,需要注意:extends 运用在 type 和 class 中时完全是两种作用的效果。

条件类型是一种条件表达式进行类型的关系检测。

简单的值匹配

type Equal<X, Y> = X extends Y ? true : false;

type Num = Equal<1, 1>; // true
type Str = Equal<'a', 'a'>; // true
type Boo = Equal<true, false>; // false

可以简单理解为一个三元表达式,当然没有那么简单,让我们更深的扒一扒。

简单的类型匹配

首先理解什么是 ”可被分配“,例如下面的这个简单且正确的类型声明与进行赋值:

const num: number = 1; // 可被分配
const str: string = 2; // 不可被分配

而条件类型的判断逻辑,和上面的的 ”可被分配“ 相同逻辑:

type IsNum<T> = T extends number ? number : string

type Num = IsNum<1>   // number;
type Str = IsNum<'1'> // string;

嵌套类型匹配

就像 if 语句一个道理,可以无限嵌套。下面写一个:根据值类型,获取值类型名称的函数类型(这也是官方给的例子):

type TypeName<T> =
    T extends string    ? "string" :
    T extends number    ? "number" :
    T extends boolean   ? "boolean" :
    T extends undefined ? "undefined" :
    T extends Function  ? "function" :
    "object";

type T0 = TypeName<string>;  // "string"
type T1 = TypeName<"a">;     // "string"
type T2 = TypeName<true>;    // "boolean"
type T3 = TypeName<() => void>;  // "function"
type T4 = TypeName<string[]>;    // "object"

判断联合类型

type A = 'x';
type B = 'x' | 'y';

type Y = A extends B ? true : false; // true

其中联合类型 A 的所有子类型,在联合类型 B 中存在,则条件满足。 如果我们把返回值替换为其他的类型定义,就能根据判断,得出想要的类型。

当联合类型无法做出判断时

我们编写一个 函数类型,逻辑很简单:给的类型是 x 时返回 a 则返回 b。

type AB<T> = T extends 'x' ? 'a' : 'b';

type A = AB<'x'>;
// 得到 type A = 'a'

看上去没什么问题,那是因为我们传入了一个明确的判断值,肯定为 true。

假设我们传入不确定的值,例如一个联合类型 'x' | 'y' 会怎么样呢?判断逻辑可能是 true,也可能是 false。其实 TypeScript 也不知道该怎么办,于是乎它就把两个结果的值都返回给我们了:

type AB<T> = T extends 'x' ? 'a' : 'b';

type All = AB<'x' | 'y'>; // 非确定条件,可能是 'x' 或 'y'
// 得到 type All = 'a' | 'b';

我们得到了一个 联合类型 包含所有返回值的。

官方的解释是:此时做了 推迟解析条件类型 的处理。

推迟解析条件类型的额外效果

在得知 条件类型不确定时会返回所有的值 的特性情况下,会产生一些额外的效果。

现在我们把传入的 T 类型也一起返回,有趣的事情就发生了。且放置 T 位置不同,产生的效果也不同:

type Other = "a" | "b";
type Merge<T> = T extends "x" ? T : Other; // T 等于匹配的类型,然后加上 Other 联合类型一起返回

type Values = Merge<"x" | "y">;
// 得到 type Values = "x" | "a" | "b";
type Other = "a" | "b";
type Merge<T> = T extends "x" ? Other : T; // T 等于除匹配类型的额外所有类型(官方叫候选类型)

type Values = Merge<"x" | "y">;
// 得到 type Values = "a" | "b" | 'y';

通过这个特性,我们可以写出 Diff<T, U> 这样常用的函数类型,一个过滤功能的函数类型:

type Filter<T, U> = T extends U ? never : T;

type Values = Filter<"x" | "y" | "z", "x">;
// 得到 type Values = "y" | "z"

对于 never 将单独进行细讲,这里我们理解为 什么都没有 就行。

使用条件类型结合 映射类型 又可以组合出很多函数类型,官网也因此预置了很多高级类型(例如:Typescript 中的 Partial, Readonly, Record, Pick),之后将会分享官方定义的所有高级类型。

条件类型还提供了 infer 推断的能力,单独进行讲解 《TypeScript 条件类型的 infer 类型推断能力》

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!
代办报建

本公司承接江浙沪报建代办施工许可证。
联系人:张经理,18321657689(微信同号)。

喜欢0发布评论

12条评论

  • 游客 发表于 2个月前

    收藏了,很不错的内容!http://r6w8.yinsong.net

  • 游客 发表于 2个月前

    怎么我回帖都没人理我呢?http://kdhlpt.com/article/3708460.html

  • 乐发V1 发表于 1个月前

    我只看看不说话。。。http://05u.9twh.com

  • 8001直播 发表于 1个月前

    收藏了,很不错的内容!http://b33w.http://www.yyqdaj.com

  • telegram下载 发表于 1个月前

    没人理我,好伤心啊!https://www.desktoptg.com/

  • 游客 发表于 1周前

    楼上的心情不错啊!http://www.guangcexing.net/voddetail/daTVZSFpTPyFd.html

  • 游客 发表于 1周前

    看在楼主的面子上,认真回帖!http://www.guangcexing.net/voddetail/cJvtxAv.html

  • 指尖网 发表于 1周前

    楼主的文笔不错!http://zeqm9.cervejaesalsicha.com

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址