Comments (12)
Why are we calling this β5.2β?
from typescript.
Related #16035
from typescript.
Seems to me the real issue is this:
class GenericClass {
constructor(public value: string) { }
}
class ConcreteClass extends GenericClass {
constructor(value: string) {
super(`Concrete: ${value}`);
}
}
function foo(obj: GenericClass) {
if (obj.constructor === ConcreteClass) {
obj; // never, Wat?
}
}
It's obviously possible for obj.constructor
to be ConcreteClass
since that class is derived from GenericClass
. The error that this issue reports is simply a follow-on effect of the incorrect narrowing that gets picked up in an inferred type predicate.
from typescript.
Changed in 5.2 5.5 so probably a result of automatic type predicate inference
from typescript.
The return type of filter callback (element) => element.constructor === ConcreteClass
is inferred as element is never
in 5.5.2 because of #57465. I would suggest using (element) => element instanceof ConcreteClass
instead.
from typescript.
Why are we calling this β5.2β?
Oops, typo and/or me being in too much of a rush. Fixed now.
from typescript.
I would suggest using
(element) => element instanceof ConcreteClass
instead.
Yes, I agree this works and is more idiomatic. I will change this in my code to fix the problem. I wanted to report it in case other projects unexpectedly break while trying to do a minor bump. I'm not sure if 5.5.2 fixes a long standing bug or not, but regardless it was a surprise to have a broken build after this minor upgrade. Thanks for your work on it π
from typescript.
@whzx5byb Thats weird though because #16035 suggests this condition doesnβt narrow
from typescript.
@fatcerberus Actually the .constructor
narrowing works only when the target is a union type and it must be compared using ===
(or ==
, but not for switch
clause) operator. I'm very surprised that it even works for the switch (true)
pattern as long as there is a ===
comparison!
class A {
a!: number;
}
class B {
b!: number;
}
function fn(input: A | B) {
switch (input.constructor) {
case A:
input.a // <- not work
}
switch (true) {
case input.constructor === A:
input.a; // work!?
}
}
But anyway, in the OP's case the narrowing target is not a union type, and .constructor ===
comparison will always narrow it to never
.
from typescript.
It goes all the way back to #32774 that implemented "constructor type guards". There is no logic to deal with derived classes.
from typescript.
#32774 that implemented "constructor type guards"
Wait, why is #16035 still open then?
from typescript.
This issue has been marked as "Design Limitation" and has seen no recent activity. It has been automatically closed for house-keeping purposes.
from typescript.
Related Issues (20)
- Incorrect Error Message: "Cannot assign to 'name' because it is a constant" Instead of "Identifier 'name' is not defined" for Undefined Identifier Assignment HOT 3
- Generic with extends yields to different type than directly specifying it HOT 5
- Instantiation expressions don't reject incompatible signatures in situations with mixed call and construct signatures HOT 1
- Parameters of overridden methods are made implicit any when using JSDoc `@override` HOT 16
- Auto complete and auto import not work (ReactJS, ChakraUI) HOT 9
- 'TypeScript and JavaScript Language Features' Formatter hangs HOT 3
- Mapped type of a conditional type unexpectedly fails inference
- Returing a generic argument from a function allows returning a wrong type HOT 2
- Module resolution behaves differently when typeRoots is specified HOT 3
- Ability to type check setters in interface implementations HOT 2
- β‘ Performance: Project service spends excess time cleaning client files when called synchronously HOT 2
- β‘ Performance: Project service doesn't cache all fs.statSync HOT 18
- jsxRuntime pragma does not work
- ThisType doesn't enforce type-checking `Object.prototype.call` HOT 5
- β‘ Performance: Project service doesn't cache all fs.realpath HOT 1
- `null` prop with `satisfies`, `strictNullChecks: false` + `noImplicitAny: true` gives any report HOT 4
- Debugging failure caused by lack of backtickοΌ`οΌ HOT 4
- [proposal] Non widened string values should be valid enum values, like widened string values HOT 1
- 'Could not find source file' with Vue plugin when creating new files and using VS Code's file watcher HOT 7
- Contextual parameters inferred from overloads improvements
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typescript.