-
Notifications
You must be signed in to change notification settings - Fork 12.8k
if ('A' in el) {}
causes code below to error
#53425
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
Comments
A slightly further reduced case: export interface I {
arr:
| { A: number; }[]
| { A: number; B: number; }[];
}
export function F(i: I) {
const useB = (n: number) => {};
for (const el of i.arr) {
if ('A' in el) {} // comment out this line to make 'useB(el.B)' compile without error
if ('B' in el) {
// When 'if ('A' in el) {}' above is not commentted out, the line below will error with:
// error : Argument of type 'unknown' is not assignable to parameter of type 'number'.(2345)
useB(el.B);
}
}
} |
This looks like a symptom of subtype reduction. At some point (probably after CFA recombines the types at the edge of the first In the past subtype reduction issues like this have been considered unfortunate, but ultimately intended behavior. |
This is indeed an effect of subtype reduction. However, subtype reduction is supposed to occur only in cases where "foreign" types (meaning types that aren't part of the declared type) are injected by narrowing, and there are no such foreign types in the example. Yet there is a |
@ahejlsberg Huh, this is the first time Iβm hearing about a hard rule for when subtype reduction is allowed to happen. Ryan usually just handwaves it as, subtype reduction can happen any time, so donβt depend on it not happening. |
@fatcerberus As a rule, subtype reduction can happen any time, but since it is costly (worst case quadratic) we labor hard to avoid it when possible. The "foreign" type detection in CFA is an example of that. |
I should add that the core issue here is the unfortunate difference between |
I agree in principle, though my suspicion is that so long as 1. users can write the latter without it being immediately reduced, and 2. unions can be narrowed, the difference will always be observableβand thus users will keep writing the latter because being able to narrow to a subtype using idiomatic (if admittedly unsound) syntax is indeed useful. |
Thank you ever so much for the impressively fast fix for this! |
@ben-clayton Just be aware that the original error is technically correct according to the rules of the type system (which is what Anders is getting at above when he says that Footnotes
|
Bug Report
π Search Terms
narrowing in if
Argument of type 'unknown'
π Version & Regression Information
β― Playground Link
Playground link with relevant code
π» Code
π Actual behavior
The above error is raised if the line
if ('A' in el) {}
is not commented out.Commenting out
if ('A' in el) {}
compiles without error.π Expected behavior
That the line
if ('A' in el) {}
does not narrow the type ofel
in a way that prevents code outside of theif
from compiling.The text was updated successfully, but these errors were encountered: