-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
User-defined type guards don't work for all types #4432
Comments
I did this intentionally to mimic the let z;
class A {}
if(z instanceof A) {
z; // any
} Should I remove it @JsonFreeman ? |
We've gone back and forth on the narrowing of I think it's fine in principle to change the rule for both type predicates and instanceof, but it depends on the impact to actual code. I do think that In other words, I think it makes the most sense as it is, but a case could be made for changing it. |
I think we can't necessarily treat it as instanceof. For example: function bob() {
var z;
if (typeof z === "boolean") {
z; // type of z is 'boolean'
}
} But abstracting into a user-defined type guard in a well-typed way actually changes what we know: function bob() {
var z;
if (isBool(z)) {
z; // type of z is still 'any'
}
} I think the reasonable assumption here is that abstraction would not lose the capability to refine the type, and that a user-defined type guard could be used instead. Not to say that you'll be making up your own booleans... but I guess I'm arguing for a solution that's general. |
@jonathandturner I see your point. The question is, when we see a type predicate of the form One idea is that if T is a primitive, we assume it's a typeof style type guard. If T is anything else, it's instanceof. Not sure if that's a good rule, but it's an idea. |
The behavior here matches the intended design. it does not match the user intuition though. we need to consider this for both instance of and user defined type guards. |
Whether or not we decide to narrow, I do think it makes sense to keep the behavior consistent between the type predicate form and the instanceof form. |
We talked about this at the design meeting and agreed this is a bug. |
Is it also a bug for instanceof? |
Doesn't this already work for instanceof? I was thinking the problem was that the ideas worked for instanceof-style checks but not typeof. |
@JsonFreeman we will need to change both user defined type guard functions and instance of. |
Right, so to summarize, the intended behavior for type predicates and instanceof, is that they should narrow when the initial type is |
correct. adding the breaking change label. |
👍 for narrowing |
We have a discussion about this and narrowing with union types available now, the user specified any explicitly (assuming noImplicitAny is on) and i would take that as an indication that she does not want more compiler checks. reverting this again because of a type guard seems more annoying than helpful. |
If the user defines a type guard for a boolean, as in this example:
...then z is not properly refined to 'boolean'. It stays 'any'. I think the expected behavior here is for the type guard to refine to boolean inside of the if check.
The text was updated successfully, but these errors were encountered: