Home > OS >  Typescript extends for excluding union members
Typescript extends for excluding union members

Time:12-13

Consider the following use of extends to remove members from a union type:

type RemoveNames<N, K> = N extends K ? never : N

type Names = 'bill' | 'jane' | 'freddy'    
type Bill = RemoveNames<Names, 'jane' | 'freddy'> // type Bill = 'bill'

In a related question, N extends K was defined to mean that "N is assignable to K", but in this case (on the face of it) N is not assignable to K - only a narrowed version of N is assignable to K.

How to interpret extends in this case? Are the members of N iterated over and "filtered" (?) if they're not in K?

CodePudding user response:

When resolving the Bill type, TypeScript takes every type of the Names union type and resolves the conditional type N extends K ? never : N, then builds a final union type with the results:

  • Does 'bill' extend 'jane' | 'freddy'? No: N extends K ? never : N gives 'bill'
  • Does 'jane' extend 'jane' | 'freddy'? Yes: N extends K ? never : N gives never
  • Does 'freddy' extend 'jane' | 'freddy'? Yes: N extends K ? never : N gives never

The final type is the union of these three types 'bill' | never | never which gives 'bill'.

This behavior is described in the Distributive Conditional Types chapter of the docs.

  • Related