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
TS2367: This condition will always return 'false' #29822
classScanner{private_index: number;private_input: string;publicgetcurrent(){returnthis._input[this._index];}constructor(input: string){this._input=input;this._index=0;}publicScan(){if(this.current=="A"){this._index++;// error TS2367: This condition will always return 'false' since the types '"A"' and '"B"' have no overlap.if(this.current=="B"){// do something}}}}
Expected behavior:
No compilation errors
Actual behavior:
error TS2367: This condition will always return 'false' since the types '"A"' and '"B"' have no overlap.
Hmm, this is a bit different than #9998 (comment) though since .current is a getter and that should be known by the compiler. It’s surprising that it performs any narrowing on it in the first place.
I don't know if TypeScript distinguishes properties obtained literally or via getters, but I'm not sure it would help much. Even if that information was made available the choices are between performing some inline effect analysis, assuming all getters are mutable, or assuming all getters are immutable.
The first two seem impractical in the general case.
That’s true, I guess it comes down to real-world tradeoffs as discussed in #9998 (is it bad I know this issue number by heart?). I guess what I find surprising is that this.getterProp is assumed to be stable and is therefore narrowed, while this.getterFunc() will never be narrowed. Since they are both function calls in the end, the inconsistency strikes me as jarring.
sorry, but this is a mistake. Getter properties should not be narrowed. How do you "convert" to a function call if I can't invoke the property as a function
Adding a simple local function wrapper around the call to the property "tricks" the compile and it now compiles... insane!
class SomeIterator {
get current(): string { ... }
moveNext(): boolean { ... }
}
function iterateOver( iterator : SomeIterator ) {
if ( iterator.current !=== "A" ) {
return;
}
iterator.moveNext();
// this throw compiler error TS2367
if (iterator.current === "B") {
}
// All case statements compiler error TS2678
switch(iterator.current) {
case "C":
break;
}
}
if I replace with the following, the compiler is now happy
class SomeIterator {
get current(): string { ... }
moveNext(): boolean { ... }
}
function iterateOver( iterator : SomeIterator ) {
let getCurrent = () => iterator.current;
if ( getCurrent() === "A" ) {
return;
}
iterator.moveNext();
// this throw compiler error TS2367
if (getCurrent () === "B") {
}
// All case statements compiler error TS2678
switch(getCurrent()) {
case "C":
break;
}
}
As properties are function under the hood, #9998 should function behaviour to properties.
Trade-offs exist. Trying to act as if things don't have a more common and less common behavior is just nihilism and doesn't make the type system more usable.
For any given value that might be stable or might not be, TS has to make an assumption one way or the other. For functions, assuming instability is going to be correct much more often than it's wrong. For properties, assuming stability is going to be correct much more often than it's wrong.
Activity
jack-williams commentedon Feb 8, 2019
Relevant comment and issue here.
fatcerberus commentedon Feb 9, 2019
Hmm, this is a bit different than #9998 (comment) though since
.currentis a getter and that should be known by the compiler. It’s surprising that it performs any narrowing on it in the first place.jack-williams commentedon Feb 9, 2019
I don't know if TypeScript distinguishes properties obtained literally or via getters, but I'm not sure it would help much. Even if that information was made available the choices are between performing some inline effect analysis, assuming all getters are mutable, or assuming all getters are immutable.
The first two seem impractical in the general case.
fatcerberus commentedon Feb 9, 2019
That’s true, I guess it comes down to real-world tradeoffs as discussed in #9998 (is it bad I know this issue number by heart?). I guess what I find surprising is that
this.getterPropis assumed to be stable and is therefore narrowed, whilethis.getterFunc()will never be narrowed. Since they are both function calls in the end, the inconsistency strikes me as jarring.typescript-bot commentedon Feb 11, 2019
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
slaneyrw commentedon Aug 26, 2019
sorry, but this is a mistake. Getter properties should not be narrowed. How do you "convert" to a function call if I can't invoke the property as a function
Adding a simple local function wrapper around the call to the property "tricks" the compile and it now compiles... insane!
if I replace with the following, the compiler is now happy
As properties are function under the hood, #9998 should function behaviour to properties.
RyanCavanaugh commentedon Aug 26, 2019
Trade-offs exist. Trying to act as if things don't have a more common and less common behavior is just nihilism and doesn't make the type system more usable.
For any given value that might be stable or might not be, TS has to make an assumption one way or the other. For functions, assuming instability is going to be correct much more often than it's wrong. For properties, assuming stability is going to be correct much more often than it's wrong.