typescript 之 Exclude 和 Extract

Exclude<T, U>

TypeScript 2.8 中增加了 Exclude 类型,该如何理解这个高级类型的定义呢?

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

Exclude 的定义来看,就是判断 T 是否继承于 U,如果是,则返回 never,否则返回 T

1. T, U 之间的关系,是否是基于结构相似呢?

interface IPerson {
  name: string,
  age: number,
  sex: 0 | 1,
}

interface IMan {
  name: string,
  age: number,
}

type Man = Exclude<IPerson, IMan> // 等效于 type Man = never

结论:只需要两者类型能够保持一致,同时 T 的类型能够兼容 U 的类型即可。

2. 对于联合类型,是如何进行类比的?

type Fruits = "apple" | "banana" | 'peach' | 'orange';
type DislikeFruits = "apple" | "banana";
type FloveFruits = Exclude<Fruits, DislikeFruits> // 等效于 type FloveFruits = "peach" | "orange"

// 实际上 Exclude 进行的比较
type FloveFruits =
  | ("apple" extends "apple" | "banana" ? never : "apple")
  | ("banana" extends "apple" | "banana" ? never : "banana")
  | ("peach" extends "apple" | "banana" ? never : "peach")
  | ("orange" extends "apple" | "banana" ? never : "orange")
// 所以最后的结果
type FloveFruits = "peach" | "orange"

当入参是联合类型时,它会以分布式的形式去进行比较。

Extract<T, U>

Extract 的功能,与 Exclude 相反,它是 提取 T 中可以赋值给 U 的类型。

type Extract<T, U> = T extends U ? T : never

1. T, U 之间的关系,是否是基于结构相似呢?

interface IPerson {
  name: string,
  age: number,
  sex: 0 | 1,
}

interface IMan {
  name: string,
  age: number,
}

type Man = Extract<IPerson, IMan> // 等效于 type Man = IPerson

Exclude 相同,均是保持相同的结构即可,只不过他们的取值逻辑相反。

2. 对于联合类型,是如何进行类比的?

type Fruits = "apple" | "banana"  | 'peach' | 'orange';
type DislikeFruits = "apple" | "banana";
type FloveFruits = Extract<Fruits, DislikeFruits> // 等效于 type FloveFruits = "apple" | "banana"

原理与 Exclude 类似,仅仅是取值的逻辑不同而已。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值