-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Empty intersection reduction #31838
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
Merged
Merged
Empty intersection reduction #31838
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
d4c9f24
Intersections of disjoint types become never upon construction
ahejlsberg 9cc9fb9
Update tests
ahejlsberg d872b3a
Accept new baselines
ahejlsberg d2397e0
Fix minor issue
ahejlsberg aa0ea51
Update fourslash tests
ahejlsberg 98bbb22
Add tests
ahejlsberg 015f4c5
Accept new baselines
ahejlsberg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
tests/baselines/reference/intersectionReduction.errors.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
tests/cases/conformance/types/intersection/intersectionReduction.ts(40,1): error TS2322: Type 'any' is not assignable to type 'never'. | ||
tests/cases/conformance/types/intersection/intersectionReduction.ts(41,1): error TS2322: Type 'any' is not assignable to type 'never'. | ||
|
||
|
||
==== tests/cases/conformance/types/intersection/intersectionReduction.ts (2 errors) ==== | ||
declare const sym1: unique symbol; | ||
declare const sym2: unique symbol; | ||
|
||
type T1 = string & 'a'; // 'a' | ||
type T2 = 'a' & string & 'b'; // never | ||
type T3 = number & 10; // 10 | ||
type T4 = 10 & number & 20; // never | ||
type T5 = symbol & typeof sym1; // typeof sym1 | ||
type T6 = typeof sym1 & symbol & typeof sym2; // never | ||
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never | ||
|
||
type T10 = string & ('a' | 'b'); // 'a' | 'b' | ||
type T11 = (string | number) & ('a' | 10); // 'a' | 10 | ||
|
||
type N1 = 'a' & 'b'; | ||
type N2 = { a: string } & null; | ||
type N3 = { a: string } & undefined; | ||
type N4 = string & number; | ||
type N5 = number & object; | ||
type N6 = symbol & string; | ||
type N7 = void & string; | ||
|
||
type X = { x: string }; | ||
|
||
type X1 = X | 'a' & 'b'; | ||
type X2 = X | { a: string } & null; | ||
type X3 = X | { a: string } & undefined; | ||
type X4 = X | string & number; | ||
type X5 = X | number & object; | ||
type X6 = X | symbol & string; | ||
type X7 = X | void & string; | ||
|
||
// Repro from #31663 | ||
|
||
const x1 = { a: 'foo', b: 42 }; | ||
const x2 = { a: 'foo', b: true }; | ||
|
||
declare let k: 'a' | 'b'; | ||
|
||
x1[k] = 'bar' as any; // Error | ||
~~~~~ | ||
!!! error TS2322: Type 'any' is not assignable to type 'never'. | ||
x2[k] = 'bar' as any; // Error | ||
~~~~~ | ||
!!! error TS2322: Type 'any' is not assignable to type 'never'. | ||
|
||
const enum Tag1 {} | ||
const enum Tag2 {} | ||
|
||
declare let s1: string & Tag1; | ||
declare let s2: string & Tag2; | ||
|
||
declare let t1: string & Tag1 | undefined; | ||
declare let t2: string & Tag2 | undefined; | ||
|
||
s1 = s2; | ||
s2 = s1; | ||
|
||
t1 = t2; | ||
t2 = t1; | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,69 @@ | ||
//// [intersectionReduction.ts] | ||
// @strict | ||
|
||
declare const sym1: unique symbol; | ||
declare const sym2: unique symbol; | ||
|
||
type T1 = string & 'a'; // 'a' | ||
type T2 = 'a' & string & 'b'; // 'a' & 'b' | ||
type T2 = 'a' & string & 'b'; // never | ||
type T3 = number & 10; // 10 | ||
type T4 = 10 & number & 20; // 10 & 20 | ||
type T4 = 10 & number & 20; // never | ||
type T5 = symbol & typeof sym1; // typeof sym1 | ||
type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 | ||
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 | ||
type T6 = typeof sym1 & symbol & typeof sym2; // never | ||
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never | ||
|
||
type T10 = string & ('a' | 'b'); // 'a' | 'b' | ||
type T11 = (string | number) & ('a' | 10); // 'a' | 10 | ||
|
||
type N1 = 'a' & 'b'; | ||
type N2 = { a: string } & null; | ||
type N3 = { a: string } & undefined; | ||
type N4 = string & number; | ||
type N5 = number & object; | ||
type N6 = symbol & string; | ||
type N7 = void & string; | ||
|
||
type X = { x: string }; | ||
|
||
type X1 = X | 'a' & 'b'; | ||
type X2 = X | { a: string } & null; | ||
type X3 = X | { a: string } & undefined; | ||
type X4 = X | string & number; | ||
type X5 = X | number & object; | ||
type X6 = X | symbol & string; | ||
type X7 = X | void & string; | ||
|
||
// Repro from #31663 | ||
|
||
const x1 = { a: 'foo', b: 42 }; | ||
const x2 = { a: 'foo', b: true }; | ||
|
||
declare let k: 'a' | 'b'; | ||
|
||
x1[k] = 'bar' as any; // Error | ||
x2[k] = 'bar' as any; // Error | ||
|
||
const enum Tag1 {} | ||
const enum Tag2 {} | ||
|
||
declare let s1: string & Tag1; | ||
declare let s2: string & Tag2; | ||
|
||
declare let t1: string & Tag1 | undefined; | ||
declare let t2: string & Tag2 | undefined; | ||
|
||
s1 = s2; | ||
s2 = s1; | ||
|
||
t1 = t2; | ||
t2 = t1; | ||
|
||
|
||
//// [intersectionReduction.js] | ||
// @strict | ||
// Repro from #31663 | ||
var x1 = { a: 'foo', b: 42 }; | ||
var x2 = { a: 'foo', b: true }; | ||
x1[k] = 'bar'; // Error | ||
x2[k] = 'bar'; // Error | ||
s1 = s2; | ||
s2 = s1; | ||
t1 = t2; | ||
t2 = t1; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Counterexample:
we handle this incorrectly in
master
already - I'm just not a fan of propagating the logical error.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So is the reason for that that the code highlighted considers
A.Zero
and0
to be distinct? I'm just trying to ascertain where in that example above thenever
creeps in.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@weswigham I think it is debatable whether we want to consider literals and literal enum members with the same underlying value to be intersectable. But either way, it is an issue that should be covered in a separate PR. Here we're just concerned with changing when we reduce, not how.