用最简单的话讲解Utility Types-Exclude&Extract

945 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

尬聊

  • Q: 猪猪萌新,根据官方文档,接下去应该是讲Omit了吧
  • A: 对,但我就是不讲,你拿我怎么办
  • Q: 那为什么要跳着讲啊,这不科学啊
  • A: 我自然有自己的想法啦,因为Omit功能用到了我们今天要讲的Exclude哦
  • Q: 那为什么你还要在讲Extract?
  • A: 那是因为Exclude和Extract长的很像,他们实现上也很接近啦哈哈

正文

一口气讲2个,不知道XDM顶不顶的住,但这2个真的很简单,不信我们接下来看下

官方例子

先来看下官方Exclude的例子,以及说明,该功能主要是排除,我就直接注释里讲解

Constructs a type by excluding from Type all union members that are assignable to ExcludedUnion.

type T0 = Exclude<"a" | "b" | "c", "a">;
     
// type T0 = "b" | "c", a和b和c,我排除a之后还剩谁,大声告诉我,对,当然就只有b和c啦

type T1 = Exclude<"a" | "b" | "c", "a" | "b">;
     
// type T1 = "c",a和b和c,我排除a和b之后还剩谁,大声告诉我,对,当然只剩c啦

type T2 = Exclude<string | number | (() => void), Function>;
     
// type T2 = string | number,string和number还有个方法,我排除方法后还剩谁,当然就只有string和number啦

再来看下官方Extract的例子,以及说明,该功能我理解就是取交集,照样注释里讲解

Constructs a type by extracting from Type all union members that are assignable to Union.

type T0 = Extract<"a" | "b" | "c", "a" | "f">;
     
// type T0 = "a", abc和af取交集,那不就是a是公共部分嘛

type T1 = Extract<string | number | (() => void), Function>;
     
// type T1 = () => void,(string,number,方法)和方法取交集,得到了方法,这就是他们的公共交集

所以基于上面的讲解,我们来个小题再来测试下

type Test1 = Exclude<"a" | "b" | "c", "a">;
type Test2 = Extract<"a" | "b" | "c", "a">;

答案公布

  • Test1 排除a,那就是"b" | "c"
  • Test2 取交集,那就是"a"

源码讲解

直接上源码

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

/**
 * Extract from T those types that are assignable to U
 */
type Extract<T, U> = T extends U ? T : never;

看实现,不难发现,其实这俩兄弟,就是倒过来的,以Exclude来举例,T extends U ? never : T这就是三目, 还记得前面我们type Test1 = Exclude<"a" | "b" | "c", "a">;排除a,只剩bc嘛,这边带入实现看,就是这样子的逻辑

  • a extends a -> 返回never -> 所以a类型被排除了
  • b extends a -> 返回T -> 所以b类型保留
  • c extends a -> 返回T -> 所以c类型保留 最后就只有bc保留了,XDM可以在捋一下Extract的实现,最后在自己手动实现下,稳稳的就能掌握啦,今天的水文到此结束!

参考