Skip to content

union optimization #25037

Closed
Closed
@amir-arad

Description

@amir-arad

I'm using union type expression to express the result of merging two objects. however it's being optimized in a way that changes (over-eager?) type inference behavior.

TypeScript Version:
3.0.0-dev.20180616 , 2.9.1-insiders.20180525

Search Terms:
union optimization inference merge

Code
I've tried to simplify it as much as I can while still keeping some 'real-world' relevance.

type Argument<T> =  {
    [P in keyof T]: T[P]; // in the real use case it's `[P in keyof T]: SomeType<T[P]>`
};
class Context<T> {
    constructor(private arg: Argument<T>) {
    }
    get<T1 extends keyof T>(key: T1): T[T1]{
        return this.arg[key]; // in the real use case it's `this.arg[key].something()`
    }
}
declare function merge2<T1, T2>(arg1: Argument<T1>, arg2: Argument<T2>): Argument<T1 | T2>;
let a = merge2({foo: { foobar: true }}, {foo: { foobar: 4 }});
const res = new Context(a).get('foo').foobar;

Expected behavior:
I expect this code to compile, and res to be of type number | boolean

Actual behavior:
Compilation fails .
using a custom union type expression works, however:

// replaces T1 | T2 expression in the type of merge2's result
type Union<T1, T2> = {
    [P in keyof (T1| T2)]: P extends keyof T1 ? P extends keyof T2 ? T1[P] | T2[P]: T1[P] : P extends keyof T2 ? T2[P] : never;
}

Playground Link:
the bug

Related Issues:
#18043

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions