-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Union Type inference not working in class (ts version 1.4) #1706
Comments
I am able to remove the error only by using explicit type assertion (<string[]>this.name).forEach((elem)=>{
console.log(elem);
});
return (<string[]>this.name).join(" "); |
Type guards only work on simple variables, not properties of an object, so you need to copy the property into a local variable. type NameOrNameArray = string | string[];
class NameCreator {
constructor(public name: NameOrNameArray) {}
createName(): string {
var name = this.name; // Copy into variable
if (typeof name === "string") {
return name;
}
else {
name.forEach(elem => {
console.log(elem);
});
return name.join(" ");
}
}
} We have this restriction because we want to track (to the best of our abilities) that there are no assignments to the variable in the guarded section. This is pretty much impossible to do correctly for properties without extensive flow and alias analysis. For example: function printString(s: string) { ... }
class Foo {
name: string | string[];
foo() {
if (typeof this.name === "string") {
this.bar();
printString(this.name); // Ok?
}
}
bar() {
this.name = ["hello"];
}
} This is just a simple example. You can construct increasingly impossible ones with little effort. A possible alternative to our current design is to allow type guards to work on dotted names of the form |
Thanks, i get a much better understanding of type guard. The use of class properties or 'global variables' doesn't really make sense as it's pretty much impossible to make sure that the condition |
Hi, is this issue going to be fixed? |
We still need to work out the exact semantics of how this would work. It's less clear exactly what forms should be allowed since non-local effects are much easier on class members. Consider, for example: class Thing {
x: string|number;
ensureXisString() {
this.x = this.x.toString();
}
someMethod() {
if(typeof this.x === 'number') {
this.ensureXisString();
// Narrowed to this.x: number here, which is 100% wrong
}
}
} |
It would be nice if type guards recognised this doesn't seem to work either (v1.4) |
@danieljsinclair The |
Tentatively approved. Need to see how this impacts real-world code. |
Just looking at old issues; this one was fixed in TS 2.0 when control flow analysis was introduced. |
Hi,
Union type inference is not working inside classes functions. For example trying to compile the below code :
gives the error :
The same code works well when using a function. Same error in Visual studio and in the Playground.
The text was updated successfully, but these errors were encountered: