-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Improve intersection reduction and CFA for truthy, equality, and typeof checks #49119
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
|
@typescript-bot test this |
|
Heya @ahejlsberg, I've started to run the abridged perf test suite on this PR at 39326d7. You can monitor the build here. Update: The results are in! |
|
Heya @ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at 39326d7. You can monitor the build here. |
|
Heya @ahejlsberg, I've started to run the extended test suite on this PR at 39326d7. You can monitor the build here. |
|
Heya @ahejlsberg, I've started to run the diff-based community code test suite on this PR at 39326d7. You can monitor the build here. Update: The results are in! |
|
@ahejlsberg Here they are:Comparison Report - main..refs/pull/49119/merge [async]1 of 1 projects failed to build with the old tsc /mnt/ts_downloads/async/tsconfig.json
|
|
@ahejlsberg Here they are:Comparison Report - main..49119
System
Hosts
Scenarios
Developer Information: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@typescript-bot test this |
|
Heya @ahejlsberg, I've started to run the abridged perf test suite on this PR at 986963c. You can monitor the build here. Update: The results are in! |
|
Heya @ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at 986963c. You can monitor the build here. |
|
Heya @ahejlsberg, I've started to run the diff-based community code test suite on this PR at 986963c. You can monitor the build here. |
|
Heya @ahejlsberg, I've started to run the extended test suite on this PR at 986963c. You can monitor the build here. |
|
@ahejlsberg Here they are:Comparison Report - main..49119
System
Hosts
Scenarios
Developer Information: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@user test this inline |
|
Is there a reason why this narrowing wasn't implemented for |
|
I feel like that's an oversight and probably deserves its own issue. (But, I'm not Anders 😄) |
|
It seems that in the examples in the main message in the function f5<T>(x: T) {
...
if (x !== undefined && x !== null) {
x; // {} -- should be T & {}
}
else {
x; // T
}
if (x != undefined) {
x; // {} -- should be NonNullable<T>
}
else {
x; // T
}
if (x != null) {
x; // {} -- should be NonNullable<T>
}
else {
x; // T
}
}But this is clear from the context and will not confuse anyone too much, I think. |
This PR introduces a number of changes affecting control flow analysis of truthy, equality, and typeof checks involving type
unknownand unconstrained type variables in--strictNullChecksmode. Key to these changes is the fact that{}, the empty object type literal, is a supertype of all types exceptnullandundefined. Thus,{} | null | undefinedis effectively equivalent tounknown, and for an arbitrary typeT, the intersectionT & {}represents the non-nullable form ofT.The PR introduces the following new behaviors:
{}.NonNullable<T>is now an alias forT & {}.T & {}, whereTis non-generic and notnullorundefined, reduces to justT(null & {}andundefined & {}already reduce tonever). See below for exceptions forstring & {},number & {}, andbigint & {}.undefined & voidreduces to justundefined.{},null, andundefined.unknownbehaves similarly to the union type{} | null | undefined.{}in the true branch.nullorundefined, generic types are intersected with{},{} | null, or{} | undefinedin the false branch.typeof x === "object"expressions, generic types are intersected withobjectand/ornullin the true branch (typeofchecks for other types already produce intersections in a similar manner).Some examples:
Note the manner in which types are properly inferred, combined, and reduced in the
ensureNotXXXfunctions. This contrasts with theNonNullable<T>conditional type provided inlib.d.ts, which unfortunately combines and reduces poorly. For example,NonNullable<NonNullable<T>>doesn't inherently reduce toNonNullable<T>, sometimes leading to needlessly complex types. For this and other reasons we intend to investigate switchingNonNullable<T>to be an alias forT & {}.For backwards compatibility, special exceptions to the
T & {}type reduction rules existing for intersections written explicitly asstring & {},number & {}, andbigint & {}(as opposed to created through instantiation of a generic typeT & {}). These types are used in a few frameworks (e.g.reactandcsstype) to construct types that permit anystring,number, orbigint, but has statement completion hints for common literal values. For example:The special
string & {}type prevents subtype reduction from taking place in the union type, thus preserving the literal types, but otherwise anystringvalue is assignable to the type.This PR reinstatates #48366 (which was removed from 4.7 due to concerns over breaking changes).
Fixes #23368.
Fixes #31908.
Fixes #32347.
Fixes #43997.
Fixes #44446.
Fixes #48048.
Fixes #48468.
Fixes #48691.
Fixes #49005.
Fixes #49191.