Closed
Description
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'.
Related Issues: #30152 looks similar