-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Narrow on element access of literal #26424
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
Conversation
This means that, for example, the tuple `[number, string?]` allows its second element to be narrowed with element access: ```ts export function f(pair: [number, string?]): string { return pair[1] ? pair[1] : 'nope'; } ```
Webpack breaks with this pattern: // @Filename: declarations.d.ts
declare function mappy(map: { [s: string]: number }): void;
// @Filename: Compilation.js
export class C {
constructor() {
/** @type {{ [assetName: string]: number}} */
this.assets = {};
}
m() {
// Error: '{}' is not assignable to '{ [assetName: string]: number }'
mappy(this.assets)
}
} Note that this is because of our this-property assignment inference; the equivalent Typescript code doesn't treat the initializer of a class' property declaration as a narrowing assignment. Edit: Never mind, this is not narrowing, and it repros on master. I'll fix it separately. |
No breaks from Definitely Typed either, so I'm pretty confident that the Breaking Change label on this PR is only theoretical code that we happen to have in our test suite. |
This means that, for example, the tuple
[number, string?]
allows its second element to be narrowed with element access:Or you can narrow on properties that don't work with property access:
This only works for actual literal references, not expressions with literal types, to prevent the binder from making the control flow graph much bigger than it is currently. In other words, this doesn't work:
Performance is not significantly different from today, even on the Compiler, Unions Edition, which is full of very large unions:
Finally, unions with index signatures behave slightly differently:
Which is visible in one baseline change. I'll check the user tests and Definitely Typed, then report back.
Fixes #10530 (and probably a few others that are still open; there are tons of duplicates of this one.)