Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

条件类型:extends 用法 #1

Open
astak16 opened this issue Mar 27, 2022 · 0 comments
Open

条件类型:extends 用法 #1

astak16 opened this issue Mar 27, 2022 · 0 comments

Comments

@astak16
Copy link
Owner

astak16 commented Mar 27, 2022

普通条件类型

LeftType extends RightType ? TrueType : FalseType;

判断 LeftType 能否分配给 RightTypeRightType 一切约束条件,LeftType 都具备,也就是说 RightType 有的值 LeftType 必须要有。

type A = {
  name: string;
};

type B = {
  name: string;
};

type Bool = A extends B ? true : false; // Bool -> true

这里面 A 类型和 B 类型完全相同,两个类型都有 name 属性,所以输出为 true

type A = {
  name: string;
};

type B = {
  name: string;
  age: number;
};

type Bool = A extends B ? true : false; // Bool -> false

B 类型比 A 类型多了一个 age 属性,也就是说 A 类型不满足 B 类型的所有条件,所以输出为 false

高阶条件类型

分配率

type A1 = "x" extends "x" ? true : false; // A1 -> true
type A2 = "x" | "y" extends "x" ? true : false; // A2 -> false

这个很好理解,和上面普通条件类型是一样的。

"x" | "y" extends "x" 竖线是或的意思,这里 "y" extends "x"false,所以结果是 false

type P<T> = T extends "x" ? true : false;
type A3 = P<"x">; // A3 -> true
type A4 = P<"x" | "y">; // A4 -> boolen

P 是带参数 T 的泛型类型,其表达式和 A1A2 形式完全一样。 A3A4 是泛型类型 P 传入参数得到的类型, 代入参数后的形式和 A1A2 形式完全一样,为什么 A4 的结果是 boolean 不是 false 呢?

type P<T> = T extends "x" ? true : false;
type A4 = P<"x" | "y">;

/** 代入过程 **/

type A4 = P<"x"> | P<"y">;
// =>
type A4 = ("x" extends "x" ? true : false) | ("y" extends "x" ? true : false);

因为 T extends "x" 会应用分配率,将 "x""y" 拆开,分别代入 P<T> ,最后将结果联合起来。

特殊的 never 满足分配率

// never 是所有类型的子类型
type A5 = never extends "x" ? true : false; // A5 -> true

type P<T> = T extends "x" ? true : false;
type A6 = P<never>; // A6 -> never

A6 的结果和 A5 居然不一样,因为 never 是所有类型的子类型(包括联合类型),所以它还是满足分配率的,只是 never 没有类型可以分配,也就没有执行后面的表达式,结果当然就是 never 了。

防止泛型使用分配率

type P<T> = [T] extends ["x"] ? true : false;

type A4 = P<"x" | "y">; // A4 -> false;
type A6 = P<never>; // A6 -> true;

[] 括起来,此时传入的泛型参数将被当做一个整体,不在分配。

要注意的是 extends 左右两个类型都要加上 [] ,否则没有用。

总结

要满足分配率有两个条件:

  1. 参数是泛型
  2. 代入的参数是联合类型

参考

Distributive Conditional Types

This was referenced Mar 31, 2022
@astak16 astak16 changed the title extends 用法 条件类型:extends 用法 May 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant