You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
typeTarget<T>=Textendsnull ? null : T;typeTarget2<T>={"one": null,"two": T}[Textendsnull ? "one" : "two"];typeTarget3<T>=[null,T][Textendsnull ? 0 : 1];functiontst<Textendsstring>(){// These two pass as expected:constcase0: Target2<T|null>=1asanyasTarget2<T|null>;constcase1: {prop: Target<T|null>}=1asanyas{prop: Target<T|null>};constcase2: {prop: Target2<T>}=1asanyas{prop: Target2<T>};constcase3: {prop: Target3<T>}=1asanyas{prop: Target3<T>};// These two fail as expected:constcase4: {prop: Target2<T>}=1asanyas{prop: Target2<T|null>};constcase5: {prop: Target3<T>}=1asanyas{prop: Target3<T|null>};// These two are expected to pass, but fail:constcase6: {prop: Target2<T|null>}=1asanyas{prop: Target2<T|null>};constcase7: {prop: Target3<T|null>}=1asanyas{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'.
This is a consequence of #30769 and fundamentally the same issue as discussed in #31833, however the trigger is slightly different.
The instantiation of the distributive conditional type T extends null ? "one" : "two" is "one" | (T extends null ? "one" : "two") as the conditional distributes over the union. The union key causes the index access type in the target type to simplify to an intersection (despite the property never being assigned), as per #30769.
TypeScript Version: Version 3.6.0-dev.20190810
Search Terms: union conditional lookup
Code
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:
Playground Link
Related Issues: #30152 looks similar
The text was updated successfully, but these errors were encountered: