4

Assuming I have this type declaration:

type Foo = 'a' | 'b' | 'c';
type Bar = 'a' | 'b' ;

Is it possible to express Bar as a subset of Foo ?

I understand it's always possible to express Foo as a superset of Bar, but in my case the other way around would feel more in line with the domain.

Kyll
  • 7,036
  • 7
  • 41
  • 64
phtrivier
  • 13,047
  • 6
  • 48
  • 79
  • Surprisingly, a dupe target exists for `Omit` but not for `Exclude` (which is what I think you are looking for). Writing an answer now... For reference: https://stackoverflow.com/q/48215950/4174897 – Kyll Jul 15 '19 at 09:24

2 Answers2

5

You simply have to use the Exclude pre-defined conditional type:

type Foo = 'a' | 'b' | 'c';
type Bar = Exclude<Foo, 'c'>;

const Bar = 'a';

Do note that the following works fine, even if it may not feel right at first glance:

type Bar = Exclude<Foo, 'd'>

See playground.


You can also combine it with index types for interesting purposes:

type Foo = 'a' | 'b' | 'c';
type AnObject = { c: boolean }
type Bar = Exclude<Foo, keyof AnObject>

const myVar: Bar = "a";
Kyll
  • 7,036
  • 7
  • 41
  • 64
2

E.g.

type Bar = Exclude<Foo, 'c'>

(documented in https://www.typescriptlang.org/docs/handbook/advanced-types.html#predefined-conditional-types)

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487