Búsqueda de sitios web

typescript - Cómo filtrar un tipo unión basado en una condición


Digamos que tengo un tipo unión de:

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

¿Hay alguna manera de crear un subconjunto que solo contenga foo?

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

Respuesta #1

Puedes escribir un tipo condicional distributivo que primero filtre por la clave deseada (foo por ejemplo) y luego filtre cualquier tipo que tenga claves adicionales probando si Exclude<FooBar, 'foo'> es 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'>