-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Union type is not narrowed by a Symbol property, even though it is correctly narrowed by a "regular" property #28701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Symbol
property
Symbol
property
control flow only narrows element access when the property name is a string or number literal (for performance reasons), see #26424 |
@solymosi do you consider user defined type guards? |
@saitonakamura They don't work either when implemented as methods on the classes: const LOADED = Symbol();
class Entity {
[LOADED](): this is Entity { return true; }
doStuff() { }
}
class ReferenceToEntity {
[LOADED](): this is Entity { return false; }
}
class SomeClass {
entity?: Entity | ReferenceToEntity;
foo() {
this.entity && this.entity[LOADED] && this.entity.doStuff();
} // ^^^^^^^ ERROR!
} ...unless the type guard is a separate function: const isLoaded = (obj: Entity | ReferenceToEntity | undefined): obj is Entity => {
return obj instanceof Entity;
}
class Entity {
doStuff() { }
}
class ReferenceToEntity { }
class SomeClass {
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. |
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. |
Uh oh!
There was an error while loading. Please reload this page.
TypeScript Version: 3.3.0-dev.20181128
Search Terms: symbol, property, key, type inference, does not narrow, union type, different behavior of symbol and string keys
Code
Expected behavior:
Since
Entity[LOADED]
is of typetrue
andReferenceToEntity[LOADED]
is of typefalse
, I would expect the type ofthis.entity
to be narrowed to justEntity
infoo()
and the above example to compile, just like it does with string property keys – i.e. this behavior seems to be unique toSymbol
properties.Actual behavior:
Compilation error:
Things that do not change the behavior:
[LOADED]
asreadonly
LOADED
asunique symbol
[LOADED]
into a getter, i.e.Things that change the behavior:
this.entity.loaded
is truthy thenthis.entity
˙must be anEntity
entity
infoo()
just before thedoStuff()
call also makes it work:Playground Link:
http://www.typescriptlang.org/play/#src=const%20LOADED%20%3D%20Symbol()%3B%0D%0A%0D%0Aclass%20Entity%20%7B%0D%0A%20%20%20%20%5BLOADED%5D%3A%20true%20%3D%20true%3B%0D%0A%20%20%20%20doStuff()%20%7B%20%7D%0D%0A%7D%0D%0A%0D%0Aclass%20ReferenceToEntity%20%7B%0D%0A%20%20%20%20%5BLOADED%5D%3A%20false%20%3D%20false%3B%0D%0A%7D%0D%0A%20%0D%0Aclass%20SomeClass%20%7B%0D%0A%20%20%20%20entity%3F%3A%20Entity%20%7C%20ReferenceToEntity%3B%0D%0A%0D%0A%20%20%20%20foo()%20%7B%0D%0A%20%20%20%20%20%20%20%20this.entity%20%26%26%20this.entity%5BLOADED%5D%20%26%26%20this.entity.doStuff()%3B%0D%0A%20%20%20%20%7D%20%20%20%20%2F%2F%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5E%5E%5E%5E%5E%5E%5E%20ERROR!%0D%0A%7D
Related Issues:
The text was updated successfully, but these errors were encountered: