题目描述
实现内置的Exclude<T, U>类型,但不能直接使用它本身。
从联合类型
T中排除U中的类型,来构造一个新的类型。
例如:
type Result = MyExclude<'a' | 'b' | 'c', 'a'> // 'b' | 'c'
题解
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type cases = [
Expect<Equal<MyExclude<'a' | 'b' | 'c', 'a'>, 'b' | 'c'>>,
Expect<Equal<MyExclude<'a' | 'b' | 'c', 'a' | 'b'>, 'c'>>,
Expect<Equal<MyExclude<string | number | (() => void), Function>, string | number>>,
]
// ============= Your Code Here =============
type MyExclude<T, U> = T extends U ? never : T;
1、TypeScript 处理联合类型的条件判断时,会依次对每一个成员进行单独的判断
例如,MyExclude<'a' | 'b' | 'c', 'a'>,也就是分别判断'a' extends 'a'、'b' extends 'a'、'c' extends 'a'
'a' extends 'a'成立,返回never
'b' extends 'a'不成立,返回'b'
'c' extends 'a'不成立,返回'c'
最后再把每个结果合并起来,形成最终的返回类型。在 TypeScript 中,当联合类型中出现never时,由于never表示不存在的值,所以在合并联合类型的过程中,never会被自动忽略或者说舍弃掉。所以最终合并的结果是'b' | 'c'