TypeScript Version: 3.1
Search Terms: switch, if, switch this
Code
class MyClass{
myString: string;
setString() {
this.myString = "c";
}
doSomeSwitching() {
switch (this.myString) {
case "a":
this.setString();
if (this.myString == "c") {
}
break;
default:
break;
}
}
}
Expected behavior:
I would expect no error.
Actual behavior:
An error is generated for the if statement.
if (this.myString == "c")
This condition will always return 'false' since the types '"a"' and '"c"' have no overlap.
The code above is the simplest form. In real use I was creating a parser. Using an instance variable to step through tokens. I check the token type with the case and then "eat" the token. The instance variable is then changed after which I want to check the token again.
Playground Link:
Link
Related Issues: I couldn't find anything that looked like this. Honestly I was mostly looking at the examples they gave since I'm not sure what many of the big words mean.
Interesting problem 馃 I changed it so it would work but solution is not the best, but should be fine. You need to write to myString directly instead of writing to it in method, well you can but need to write it in the "case" so it won't show that error.
class MyClass{
myString: string;
setString(new_s) {
this.myString = new_s;
return this.myString // <--- added this line
}
doSomeSwitching() {
switch (this.myString) {
case "a": {
this.myString = this.setString("c") // <-- solution to this problem is to modify
// myString directly so TypeScript know's that it was changed to different value
if (this.myString == "c")
{
}
break;
}
default: {
// ok
}
}
}
}
}
Nice, I didn't think of doing that. I found that any assignment will make it happy. So you don't even have to mess with the function.
class MyClass{
myString: string;
setString() {
this.myString = "c";
}
doSomeSwitching() {
switch (this.myString) {
case "a":
this.setString();
this.myString = this.myString; // <-- Adding this takes the error away.
if (this.myString == "c") {
}
break;
default:
break;
}
}
}
This is a design limitation. See discussion in #9998.
Is there any real-world benefit to the type being narrowed to a literal inside the cases?
this.myString = this.myString;
Why does this work to widen the type? In the example given, TS thinks the type of myString is "a" at that point, so assigning it to itself causing it to be widened seems counterintuitive.
Most helpful comment
This is a design limitation. See discussion in #9998.