00043-easy-exclude

Back

1.题目

实现内置的 Exclude<T, U> 类型,但不能直接使用它本身。 从联合类型 T 中排除 U 中的类型,来构造一个新的类型。 例如:

type Result = MyExclude<'a' | 'b' | 'c', 'a'> // 'b' | 'c'

2.解答

type MyExclude<T, U> = T extends U ? never : T
// 分发过程:
// 第一步:'a' extends 'a' ? never : 'a'  → never
// 第二步:'b' extends 'a' ? never : 'b'  → 'b'  
// 第三步:'c' extends 'a' ? never : 'c'  → 'c'

// 最终结果:never | 'b' | 'c' → 'b' | 'c'

3.解析

首先,这里T是联合类型,联合类型的意思不是指包括的类型都存在,而是说都有可能,所以说使用extends可以判断单一类型是否可以赋值给联合类型,并使用never清除单一类型

never 的作用

在联合类型中,never 会被自动过滤掉:

type Example = 'a' | never | 'b' | never 
// 等价于 'a' | 'b'

工作原理

  1. 条件类型分发:当 T 是联合类型时,T extends U ? X : Y 会进行分发(distributive)
  2. 逐个判断:对联合类型中的每个成员进行条件判断
  3. 排除逻辑:如果成员可以赋值给 U,则返回 never(排除),否则保留原类型

深入理解条件类型的分发

什么是分发(Distribution)?

当条件类型作用于裸类型参数(naked type parameter)时,会发生分发:

// 裸类型参数 - 会发生分发
type Distributive<T> = T extends any ? [T] : never
type Test1 = Distributive<'a' | 'b'> // ['a'] | ['b']

// 非裸类型参数 - 不会发生分发  
type NonDistributive<T> = [T] extends any ? [T] : never
type Test2 = NonDistributive<'a' | 'b'> // ['a' | 'b']

Solution by nyk233233 #37475

type MyExclude<Type, ExcludedItems> = Type extends ExcludedItems ? never : Type

Solution by Muntazir-sd #37429

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

Solving this challenge using [Typescript Distributive Conditional Types](https://stackoverflow.com/a/55383816)


In plain words

MyExclude<T, U> constructs a new type by:

  1. Taking each type inside T.
  2. Checking if it is assignable to U.
  3. If yes → remove it (never).
  4. If no → keep it.

✅ Example:

type Result = MyExclude<"a" | "b" | "c", "a" | "c">
// Step by step:
// "a" extends "a" | "c" → never
// "b" extends "a" | "c" → "b"
// "c" extends "a" | "c" → never
// Result: "b"

So Result is "b". 🎯

Solution by 3aluw #37427

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

Solution by djdidi #37128

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

Solution by 359Steve #37015

Here T extends U check if T includes U or not. Using this clever technique we can exclude.

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

Solution by Anonymous961 #36965

// your answers
type MyExclude<T, U> = T extends U ? never : T;

Solution by AlexBraunMagic #36916

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

Solution by shaishab316 #36843

// 题目
type Result = MyExclude<'a' | 'b' | 'c', 'a'> // 'b' | 'c'
// 你的答案
type MyExclude<T, U> =  T extends U ? never : T;

Solution by mola-fish #36831

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

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/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>>,
]

Solution by AnastasiaSv #36763

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

Solution by seungdeok #36661

// your answers

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

Solution by vva-sync #36627

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

Solution by tjd985 #36616

// 你的答案
type MyExclude<T, U> = T extends U ? never : T

Solution by MrSissel #36582

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

Solution by ChemieAi #36551


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

Solution by gakki-san #36477

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

Solution by alirezaprime #36413

// your answers
type MyExclude<T, U> = T extends U ? never : T

Solution by ATravelerGo #36370

// your answers
type MyExclude<T, U> = T extends U ? never : T;

Solution by justBadProgrammer #36360

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

Solution by 1Alex4949031 #36311

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

Solution by Jace254 #36268

type MyExclude<T, U> = T extends infer K ? K extends U ? never : K : never

Solution by Maxim-Do #36226

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

Solution by asylbekduldiev #36182

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

Solution by AleksandrShcherbackov #36143

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

Solution by KimKyuHoi #36127

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

Solution by buglavecz #36094

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

Solution by karazyabko #36027

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

Solution by codingaring #35935

// your answers

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

Solution by pytest5 #35924

// 你的答案
type MyExclude<T, U> =  T extends U ? never : T;

Solution by reonce #35917