I have a String Union that looks like:
type AlphabetLike = 'a' | 'b' | 'c' | 'zeta' | 'beta' | 'gamma' | 'mu';
I want to be able to construct the type
type Alphabet = 'a' | 'b' | 'c'
. I could do this by using Exclude and removing zeta, beta, gamma, and mu but that's a lot of things to remove and if more values are added to AlphabetLike, it changes Alphabet. I want to know if my value from "AlphabetLike" is ever removed from that type.
Is there a way to do an Include instead of an Exclude?
CodePudding user response:
A double "exclude" can act as an include.
First, create a list of all of the items you want to exclude if you were using exclude.
type GreekAlphabet = Exclude<AlphabetLike, 'a' | 'b' | 'c'>
This results in a set that is:
'zeta' | 'beta' | 'gamma' | 'mu'
We can use that set with Exclude to give us back the values we want:
type Alphabet = Exclude<AlphabetLike, GreekAlphabet>
This results in:
'a' | 'b' | 'c'
which is effectively Include<AlphabetLike, 'a'|'b'|'c'>
and will protect you if an option in use is removed from "AlphabetLike".
CodePudding user response:
Instead of custructing Alphabet as an exclusion of types from AlphabetLike, construct AlphabetLike as a union of different alphabet types.
type Alphabet = 'a' | 'b' | 'c';
type GreekAlphabet = 'zeta' | 'beta' | 'gamma' | 'mu';
type AlphabetLike = Alphabet | GreekAlphabet;
CodePudding user response:
There is an Extract<T, U>
utility type which acts like the opposite of the Exclude<T, U>
utility type:
type AlphabetLike = 'a' | 'b' | 'c' | 'zeta' | 'beta' | 'gamma' | 'mu';
type Alphabet = Extract<AlphabetLike, 'a' | 'b' | 'c' | 'zzz'>;
// type Alphabet = "a" | "b" | "c"
Note that nothing forces the second argument (called U
here) to either Extract<T, U>
or Exclude<T, U>
to contain only elements from the first argument (called T
here). Hence that 'zzz'
above doesn't have an effect on anything.