Exclude
问题描述
实现内置的 Exclude<T, U> 类型,但不能直接使用它本身。
从联合类型
T中排除U中的类型,来构造一个新的类型。
例如:
type Result = MyExclude<'a' | 'b' | 'c', 'a'> // 'b' | 'c'
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type Fruit = 'apple' | 'banana' | 'orange'
// type Result = Exclude<Fruit, "orange">; // Result 类型将是 "apple" | "banana"
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>>, Expect<Equal<MyExclude<Fruit, 'orange'>, 'apple' | 'banana'>>]
// ============= Your Code Here =============
// 答案
type MyExclude<T, U> = T extends U ? never : T
exclude 意为排除某个 type 或者 interface 中的属性,实际上,我们只需要遍历所有属性,判断属性是否和 MyExclude 传入的第二个泛型参数相同即可,关键点就在于,如何判断相同,这里使用了 T extends U,大范围是否继承自小范围,这和该项目中的 type Expect<T extends true> = T 有异曲同工之妙,使用小范围去约束大范围来筛选,如果不是,则返回 T,是则返回 never,这样就排除掉了泛型中的某个属性。