Let's suppose I have following types defined:
type A = {a:number};
type B = {a:string};
type C = {a:boolean};
type All = A | B | C;
Now I want to define generic type S
(not using any of the types A
,B
and C
in the definition) that behaves like that:
var a: S<A>; // a is actually of type A
var b: S<B>; // b is of type B
var c: S<C>; // c is of type C
var all: S<All>; // all is of type never
To achieve that I can define S
like that:
type S<T> = All extends T ? never : T;
However this is not sufficient for me because I also want that
var ab: S<A|B>; // ab should be type never but actually is A|B
var bc: S<B|C>; // bc should be type never but actually is B|C
var ca: S<C|A>; // ca should be type never but actually is C|A
Given some union type, how to define generic type that can be matched to every single constituent of the union type, but can't be matched to any union of those constituents?
Solution should also work for union types with more than 3 constituents.
It seems that this does exactly what I want:
type S<T> = [T] extends (T extends All ? [T] : never) ? T : never;