Search code examples
typescriptmapped-types

Extend Discriminated Unions


is it possible to do transform this DU using mappend/conditional types

type MyDU =
| {kind: 'foo'}
| {kind: 'bar'}

type Transformed = DUTransformer<MyDU>

such that we get the folllowing result

type Transformed =
| {kind: 'foo', foo: boolean}
| {kind: 'bar', bar: boolean}

Solution

  • Yes, because TypeScript will distribute mapped types over a union:

    type MyDU =
    | {kind: 'foo'}
    | {kind: 'bar'}
    
    type Kinded<T extends string> = { kind: T }
    
    type DUTransformer<T> = T extends Kinded<infer K> ? T & {[K1 in K]: boolean} : never
    
    type Transformed = DUTransformer<MyDU>
    

    The type of Transformed is:

    type Transformed = ({
        kind: 'foo';
    } & {
        foo: boolean;
    }) | ({
        kind: 'bar';
    } & {
        bar: boolean;
    })