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
Union type is not narrowed by a Symbol property, even though it is correctly narrowed by a "regular" property #28701
Expected behavior:
Since Entity[LOADED] is of type true and ReferenceToEntity[LOADED] is of type false, I would expect the type of this.entity to be narrowed to just Entity in foo() and the above example to compile, just like it does with string property keys – i.e. this behavior seems to be unique to Symbol properties.
Actual behavior:
Compilation error:
Property 'doStuff' does not exist on type 'Entity | ReferenceToEntity'.
Property 'doStuff' does not exist on type 'ReferenceToEntity'.
Things that do not change the behavior:
marking [LOADED] as readonly
explicitly marking LOADED as unique symbol
turning [LOADED] into a getter, i.e.
get [LOADED](): true { return true; }
disabling strict mode
Things that change the behavior:
using string property keys makes it work as intended, i.e. the compiler realizes that if this.entity.loaded is truthy then this.entity˙must be an Entity
assigning to entity in foo() just before the doStuff() call also makes it work:
foo() {
this.entity = new Entity();
this.entity && this.entity[LOADED] && this.entity.doStuff(); // NO ERROR
}
changed the title [-]Property type not inferred properly when using Symbol key[/-][+]Union type is correctly narrowed by a "regular" property but not by a `Symbol` property[/+]on Nov 28, 2018
changed the title [-]Union type is correctly narrowed by a "regular" property but not by a `Symbol` property[/-][+]Union type is not narrowed by a Symbol property, even though it is correctly narrowed by a "regular" property[/+]on Nov 28, 2018
Klaus Meinhardt (@ajafff) Oops, this is a duplicate then. Unfortunately this issue renders symbol properties unusable for our purposes without some not-so-clean workarounds, so it would be really nice to have #26424 extended with support for symbols.
constLOADED=Symbol();classEntity{[LOADED](): this is Entity{returntrue;}doStuff(){}}classReferenceToEntity{[LOADED](): this is Entity{returnfalse;}}classSomeClass{entity?: Entity|ReferenceToEntity;foo(){this.entity&&this.entity[LOADED]&&this.entity.doStuff();}// ^^^^^^^ ERROR!}
...unless the type guard is a separate function:
constisLoaded=(obj: Entity|ReferenceToEntity|undefined): obj is Entity=>{returnobjinstanceofEntity;}classEntity{doStuff(){}}classReferenceToEntity{}classSomeClass{entity?: Entity|ReferenceToEntity;foo(){isLoaded(this.entity)&&this.entity.doStuff();}// ^^^^^^^ IT WORKS!}
The latter is actually the workaround I've implemented for now, but it does not feel that clean.
Activity
[-]Property type not inferred properly when using Symbol key[/-][+]Union type is correctly narrowed by a "regular" property but not by a `Symbol` property[/+][-]Union type is correctly narrowed by a "regular" property but not by a `Symbol` property[/-][+]Union type is not narrowed by a Symbol property, even though it is correctly narrowed by a "regular" property[/+]ajafff commentedon Nov 28, 2018
control flow only narrows element access when the property name is a string or number literal (for performance reasons), see #26424
solymosi commentedon Nov 28, 2018
Klaus Meinhardt (@ajafff) Oops, this is a duplicate then. Unfortunately this issue renders symbol properties unusable for our purposes without some not-so-clean workarounds, so it would be really nice to have #26424 extended with support for symbols.
saitonakamura commentedon Nov 28, 2018
Máté Solymosi (@solymosi) do you consider user defined type guards?
solymosi commentedon Nov 28, 2018
Michael サイトー 中村 Bashurov (@saitonakamura) They don't work either when implemented as methods on the classes:
...unless the type guard is a separate function:
The latter is actually the workaround I've implemented for now, but it does not feel that clean.
typescript-bot commentedon Dec 12, 2018
This issue has been marked as a duplicate and has seen no activity in the last day. It has been closed automatic house-keeping purposes.