Phiiiiiiiiiiiii
Phiiiiiiiiiiiii

Reputation: 23

How to filter an union type based on a condition

Let's say I have an union type of:

type FooBar = {foo: 'a'} | {foo: 'b'} | {foo: 'c', bar: 'c'};

Is there a way to create a subset that only contains foo?

type OnlyFoo = SomeFilter<FooBar, 'foo'>;
// type OnlyFoo = {foo: 'a'} | {foo: 'b'};

Upvotes: 2

Views: 358

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249536

You can write a distributive conditional type that first filters by the desired key (foo for example) and then filters any type that has any extra keys by testing if Exclude<FooBar, 'foo'> is never:

type FilterByProp<T, K extends PropertyKey> = T extends Record<K, any> ? 
    Exclude<keyof T, K> extends never ? T : 
    never : never;

type FooBar = {foo: 'a'} | {foo: 'b'} | {foo: 'c', bar: 'c'};
type OnlyFoo = FilterByProp<FooBar, 'foo'>

Upvotes: 1

Related Questions