Skip to content

Assignment fails for types with conditional lookup for a union of a generic #32816

Closed
@smoogly

Description

@smoogly

TypeScript Version: Version 3.6.0-dev.20190810

Search Terms: union conditional lookup

Code

type Target<T> = T extends null ? null : T;
type Target2<T> = { "one": null, "two": T }[T extends null ? "one" : "two"];
type Target3<T> = [null, T][T extends null ? 0 : 1];

function tst<T extends string>() {
    // These two pass as expected:
    const case0: Target2<T | null> = 1 as any as Target2<T | null>;
    const case1: { prop: Target<T | null> } = 1 as any as { prop: Target<T | null> };
    const case2: { prop: Target2<T> } = 1 as any as { prop: Target2<T> };
    const case3: { prop: Target3<T> } = 1 as any as { prop: Target3<T> };

    // These two fail as expected:
    const case4: { prop: Target2<T> } = 1 as any as { prop: Target2<T | null> };
    const case5: { prop: Target3<T> } = 1 as any as { prop: Target3<T | null> };

    // These two are expected to pass, but fail:
    const case6: { prop: Target2<T | null> } = 1 as any as { prop: Target2<T | null> };
    const case7: { prop: Target3<T | null> } = 1 as any as { prop: Target3<T | null> };
}

Expected behavior:
Expected cases 6 and 7 to pass, as both sides of assignment supposed to be structurally identical.

Actual behavior:
Cases 6 and 7 fail. Example output:

error TS2719: Type '{ prop: { "one": null; "two": T | null; }["one" | (T extends null ? "one" : "two")]; }' is not assignable to type '{ prop: { "one": null; "two": T | null; }["one" | (T extends null ? "one" : "two")]; }'. Two different types with this name exist, but they are unrelated.
  Types of property 'prop' are incompatible.
    Type '{ "one": null; "two": T | null; }[T extends null ? "one" : "two"] | null' is not assignable to type 'null & { "one": null; "two": T | null; }[T extends null ? "one" : "two"]'.
      Type '{ "one": null; "two": T | null; }[T extends null ? "one" : "two"]' is not assignable to type 'null & { "one": null; "two": T | null; }[T extends null ? "one" : "two"]'.
        Type 'T | null' is not assignable to type 'null & { "one": null; "two": T | null; }[T extends null ? "one" : "two"]'.
          Type 'T' is not assignable to type 'null & { "one": null; "two": T | null; }[T extends null ? "one" : "two"]'.
            Type 'string' is not assignable to type 'null & { "one": null; "two": T | null; }[T extends null ? "one" : "two"]'.
              Type 'string' is not assignable to type 'null'.
                Type 'T' is not assignable to type 'null'.
                  Type '{ "one": null; "two": T | null; }[T extends null ? "one" : "two"]' is not assignable to type 'null'.
                    Type 'T | null' is not assignable to type 'null'.
                      Type 'T' is not assignable to type 'null'.
                        Type 'string' is not assignable to type 'null'.

Playground Link

Related Issues: #30152 looks similar

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