sajad torkamani

Solution

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<{ foo: string }, { bar: string }>, { foo: string }>>,
  Expect<Equal<MyExclude<string | number | (() => void), Function>, string | number>>,
]

How it works

The T extends U section will behave differently depending on whether T is an object type or a union type.

If T is an object type, it’ll check whether the T type has all the properties in U.

If T is a union type, it will construct a union type by doing something like:

  1. Create an empty union placeholder
  2. Iterate over each item in T and check if it’s in U.
    • If the item is in U, don’t add the item to placeholder union.
    • If the item is not in U, add it to the placeholder union.
  3. Return the placeholder union

TypeScript playground

TypeScript playground

Tagged: TypeScript