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
{{ message }}
Repository navigation
Returned Enum value has its type needlessly widened #20254
enumItem{potato="potato",cucumber="cucumber"}// inferred type is `() => Item`constgetPotato1=()=>Item.potato;// type assertion worksconstgetPotato2: ()=>Item.potato=()=>Item.potato;
Expected behavior:
Type of getPotato1 should be inferred as () => Item.potato.
Actual behavior:
Type of getPotato1 is "needlessly" widened to () => Item.
Here is an example where the return type is not a singleton literal type but a union of objects containing literal types, and the compiler still appears to widen both literal types to their enum union type:
{enumItem{potato='potato',cucumber='cucumber',}{constget=()=>true ? {item: Item.potato,otherVar: true} : {item: Item.cucumber};/* Unexpected error: Type '{ item: Item; otherVar: boolean; } | { item: Item; }' is not assignable to type '{ item: Item.potato; otherVar: boolean; } | { item: Item.cucumber; }'. Type '{ item: Item; otherVar: boolean; }' is not assignable to type '{ item: Item.potato; otherVar: boolean; } | { item: Item.cucumber; }'. Type '{ item: Item; otherVar: boolean; }' is not assignable to type '{ item: Item.cucumber; }'. Types of property 'item' are incompatible. Type 'Item' is not assignable to type 'Item.cucumber'. */constresult: {item: Item.potato;otherVar: boolean}|{item: Item.cucumber}=get();result;}}
Is this also expected behaviour, or a separate issue?
Oliver Joseph Ash (@OliverJAsh) My comment above was regarding literal types as the actual return type. In your example the return type is a union of object types, and the literal types are widened because they are inferred for a mutable location (i.e. a property in an object literal). That is the expected behavior.
Aha, good to know, thanks. Here's an example for anyone else who might be interested:
{enumItem{potato='potato',cucumber='cucumber',}{constx={item: Item.potato}/* Error: Type '{ item: Item; }' is not assignable to type '{ item: Item.potato; }'. Types of property 'item' are incompatible. Type 'Item' is not assignable to type 'Item.potato'. */constresult: {item: Item.potato;}=x;result;}// workaround 1: type assertion on property{constx={item: Item.potatoasItem.potato}constresult: {item: Item.potato;}=x;result;}// workaround 2: avoid inference{constx: {item: Item.potato;}={item: Item.potato}constresult: {item: Item.potato;}=x;result;}}
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
Activity
ahejlsberg commentedon Nov 25, 2017
This is working as intended. See #10676 (comment).
OliverJAsh commentedon Nov 25, 2017
Anders Hejlsberg (@ahejlsberg)
Interesting, thanks for the linking to that explanation!
#10676 (comment)
Here is an example where the return type is not a singleton literal type but a union of objects containing literal types, and the compiler still appears to widen both literal types to their enum union type:
Is this also expected behaviour, or a separate issue?
ahejlsberg commentedon Nov 26, 2017
Oliver Joseph Ash (@OliverJAsh) My comment above was regarding literal types as the actual return type. In your example the return type is a union of object types, and the literal types are widened because they are inferred for a mutable location (i.e. a property in an object literal). That is the expected behavior.
OliverJAsh commentedon Nov 26, 2017
Aha, good to know, thanks. Here's an example for anyone else who might be interested:
OliverJAsh commentedon Nov 26, 2017
Also for anyone else who is interested, here is some discussion about widening in object literals and a proposal to change this #20195
typescript-bot commentedon Dec 11, 2017
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.