consistently check expressions with >, >=, <, <= for unconstrained types in strictNullChecks - #59352
Conversation
|
TypeScript Bot (@typescript-bot) test it |
|
Hey Isabel Duan (@iisaduan), I've packed this into an installable tgz. You can install it for testing by referencing it in your and then running There is also a playground for this build and an npm module you can use via |
|
Hey Isabel Duan (@iisaduan), the results of running the DT tests are ready. Everything looks the same! |
|
Isabel Duan (@iisaduan) Here are the results of running the user tests with tsc comparing Everything looks good! |
|
Isabel Duan (@iisaduan) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Isabel Duan (@iisaduan) Here are the results of running the top 400 repos with tsc comparing Something interesting changed - please have a look. Details
|
|
|
||
| // use to determine if a parameter may be undefined or null (or is unknown/unconstrained) | ||
| function getUnknownIfMaybeUnknown(type: Type) { | ||
| return (strictNullChecks && type.flags & TypeFlags.Instantiable) ? getBaseConstraintOfType(type) || unknownType : type; |
There was a problem hiding this comment.
I'm assuming from #59059 that making this change to getTypeFacts breaks a lot of existing code, is that right?
Also, does making this change to checkNonNullType instead also break a lot of code?
There was a problem hiding this comment.
Yes, I tried that and putting this change directly into checkNonNullType gets a very similar result to #59059 in terms of breaking object index checking
There was a problem hiding this comment.
A lot of the cases that break relate to this type of index access #59059 (comment)
There was a problem hiding this comment.
I don't know if this it's noticeably different in semantics, but istead of doing this, you might want to try to modify getBaseTypeOfLiteralTypeForComparison and rename it getBaseTypeForComparison. Then pass the result of that into checkNonNullType.
There was a problem hiding this comment.
I would also consider renaming this to getBaseConstraintOrUnknown, use ?? instead of ||, and just get rid of the strictNullChecks check.
There was a problem hiding this comment.
Also - any clue if this works on unions of unconstrained type parameters? Can you add a test?
function f<T, U>(x: T | U, y: T | U) {
return x < y;
}|
Checking this TypeScript Bot (@typescript-bot) perf test this |
|
|
||
| // use to determine if a parameter may be undefined or null (or is unknown/unconstrained) | ||
| function getUnknownIfMaybeUnknown(type: Type) { | ||
| return (strictNullChecks && type.flags & TypeFlags.Instantiable) ? getBaseConstraintOfType(type) || unknownType : type; |
There was a problem hiding this comment.
I don't know if this it's noticeably different in semantics, but istead of doing this, you might want to try to modify getBaseTypeOfLiteralTypeForComparison and rename it getBaseTypeForComparison. Then pass the result of that into checkNonNullType.
|
|
||
| // use to determine if a parameter may be undefined or null (or is unknown/unconstrained) | ||
| function getUnknownIfMaybeUnknown(type: Type) { | ||
| return (strictNullChecks && type.flags & TypeFlags.Instantiable) ? getBaseConstraintOfType(type) || unknownType : type; |
There was a problem hiding this comment.
I would also consider renaming this to getBaseConstraintOrUnknown, use ?? instead of ||, and just get rid of the strictNullChecks check.
|
|
||
| // use to determine if a parameter may be undefined or null (or is unknown/unconstrained) | ||
| function getUnknownIfMaybeUnknown(type: Type) { | ||
| return (strictNullChecks && type.flags & TypeFlags.Instantiable) ? getBaseConstraintOfType(type) || unknownType : type; |
There was a problem hiding this comment.
Also - any clue if this works on unions of unconstrained type parameters? Can you add a test?
function f<T, U>(x: T | U, y: T | U) {
return x < y;
}|
Daniel Rosenwasser (@DanielRosenwasser) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
tsserverComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
startupComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Daniel Rosenwasser (@DanielRosenwasser) Thanks for the suggestions! Good catch--it does work for unions but not intersections, so I added those cases as well. |
|
TypeScript Bot (@typescript-bot) test it |
|
Gabriela Araujo Britto (@gabritto) Here are the results of running the user tests with tsc comparing Everything looks good! |
|
Hey Gabriela Araujo Britto (@gabritto), the results of running the DT tests are ready. Everything looks the same! |
|
Gabriela Araujo Britto (@gabritto) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Gabriela Araujo Britto (@gabritto) Here are the results of running the top 400 repos with tsc comparing Something interesting changed - please have a look. Details
|
|
I have just put up #59437 which I believe is the right fix for #50603 plus the inconsistencies related to unconstrained type parameters vs. type parameters constrained to |
|
With 6.0 out as the final release vehicle for this codebase, we're closing all PRs that don't fit the merge criteria for post-6.0 patches. If you think this was a mistake and this PR fits the post-6.0 patch criteria, please post to the 6.0 iteration issue with details (specifically, which PR and which patch criteria it satisfies). Next steps for PRs:
|
fixes #50603, which bisected to #49119
Previously: unconstrained type parameters were inconsistently checked in comparisons, as shown below (5.5.3 playground):
Now with this PR:
This PR does not affect the checking of unconstrained types in other locations.