-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Differing user-defined type guard and 'typeof' type guard behaviour when narrowing 'any' #6015
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Any thoughts on this? Looks clearly incorrect to me, but I can't find a definitive spec on user-defined type guards, which makes it difficult to verify. I'd be very surprised that they're actually intended to differ from built-in type guards in this regard though. |
The thing is that user-defined type guards are "weaker" than @ahejlsberg and I have discussed this offline and one idea we have is that for any primitive type covered by a |
If anyone is considering sending a PR for this, give a heads up here so we don't duplicate work. 😃 |
I've been playing around with the controlFlowTypes branch and it appears as if the same narrowing behavior should probably apply there as well: For example: let a: any;
a = "10";
a; // a: any ... expected a: string
a.toFixed(2); // no compile error! I have been using noImplicitAny in my own code base, but I can imagine some smarter behavior here could only help to find bugs in code which does wind up using any (whether implicitly or explicitly). |
Came up on stackoverflow : http://stackoverflow.com/a/37153565/390330 🌹 |
Writing a type guard for something that TS thinks is |
@jstaro This does not seem to be a problem with TSC > 2.2 and latest VS Code. interface User {
name: string;
}
function isUser(input: any): input is User {
return (input && input.name);
}
let x = JSON.parse('"any"');
if (isUser(x)) {
x; // Works fine now.
} else {
x;
} |
@DanielRosenwasser this should have been fixed? |
This appears to be fixed for user defined type guards, but strict equality var y: any;
// Built-in type guard
if (typeof y === "string") {
y.hello = true; // Correct error - 'hello' does not exist on type string
}
// Equivalent user-defined type guard
function f(x: any): x is string {
return typeof x === "string";
}
if (f(y)) {
y.hello = true; // This is now a correct error with latest TS version: Property 'hello' does not exist on type 'string'.
}
if(y === "hello") {
y.hello = true; // No error with strict equality guard
} Is that intentional? |
It appears to be "fixed", but I don't think that's the correct behavior? Consider the following example, I should be able to access arbitrary fields on
|
In the below code, using a typeof type guard and an equivalent (I thought) user-defined guard, only one error is produced.
Playground demo. Looks like user-defined type guards won't narrow from
any
, in any circumstances, as far as I can tell.The text was updated successfully, but these errors were encountered: