-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Intersect 'this' types in union signatures #32538
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts(10,5): error TS2684: The 'this' context of type 'Real | Fake' is not assignable to method's 'this' of type 'Real & Fake'. | ||
Type 'Real' is not assignable to type 'Real & Fake'. | ||
Type 'Real' is not assignable to type 'Fake'. | ||
Types of property 'method' are incompatible. | ||
Type '(this: Real, n: number) => void' is not assignable to type '(this: Fake, n: number) => void'. | ||
The 'this' types of each signature are incompatible. | ||
Type 'Fake' is not assignable to type 'Real'. | ||
Types of property 'data' are incompatible. | ||
Type 'number' is not assignable to type 'string'. | ||
|
||
|
||
==== tests/cases/conformance/types/thisType/unionThisTypeInFunctions.ts (1 errors) ==== | ||
interface Real { | ||
method(this: this, n: number): void; | ||
data: string; | ||
} | ||
interface Fake { | ||
method(this: this, n: number): void; | ||
data: number; | ||
} | ||
function test(r: Real | Fake) { | ||
r.method(12); // error | ||
~ | ||
!!! error TS2684: The 'this' context of type 'Real | Fake' is not assignable to method's 'this' of type 'Real & Fake'. | ||
!!! error TS2684: Type 'Real' is not assignable to type 'Real & Fake'. | ||
!!! error TS2684: Type 'Real' is not assignable to type 'Fake'. | ||
!!! error TS2684: Types of property 'method' are incompatible. | ||
!!! error TS2684: Type '(this: Real, n: number) => void' is not assignable to type '(this: Fake, n: number) => void'. | ||
!!! error TS2684: The 'this' types of each signature are incompatible. | ||
!!! error TS2684: Type 'Fake' is not assignable to type 'Real'. | ||
!!! error TS2684: Types of property 'data' are incompatible. | ||
!!! error TS2684: Type 'number' is not assignable to type 'string'. | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
tests/cases/conformance/types/union/unionTypeCallSignatures5.ts(12,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'never'. | ||
|
||
|
||
==== tests/cases/conformance/types/union/unionTypeCallSignatures5.ts (1 errors) ==== | ||
// #31485 | ||
interface A { | ||
(this: void, b?: number): void; | ||
} | ||
interface B { | ||
(this: number, b?: number): void; | ||
} | ||
interface C { | ||
(i: number): void; | ||
} | ||
declare const fn: A | B | C; | ||
fn(0); | ||
~~~~~ | ||
!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'never'. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’m not sure what to do with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok; by that logic I think the intersection stands. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this parameters,
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ declare const fn: A | B | C; | |
>fn : A | B | C | ||
|
||
fn(0); | ||
>fn(0) : void | ||
>fn(0) : any | ||
>fn : A | B | C | ||
>0 : 0 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(11,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. | ||
Type 'void' is not assignable to type 'A'. | ||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(13,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A'. | ||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(38,4): error TS2349: This expression is not callable. | ||
Each member of the union type 'F3 | F4' has signatures, but none of those signatures are compatible with each other. | ||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(39,1): error TS2684: The 'this' context of type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' is not assignable to method's 'this' of type 'B'. | ||
Property 'b' is missing in type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' but required in type 'B'. | ||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(48,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. | ||
Type 'void' is not assignable to type 'A'. | ||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(55,1): error TS2769: No overload matches this call. | ||
Overload 1 of 2, '(this: A & B & C): void', gave the following error. | ||
The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B & C'. | ||
Type 'void' is not assignable to type 'A'. | ||
Overload 2 of 2, '(this: A & B): void', gave the following error. | ||
The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. | ||
Type 'void' is not assignable to type 'A'. | ||
|
||
|
||
==== tests/cases/conformance/types/union/unionTypeCallSignatures6.ts (6 errors) ==== | ||
type A = { a: string }; | ||
type B = { b: number }; | ||
type C = { c: string }; | ||
type D = { d: number }; | ||
type F0 = () => void; | ||
|
||
// #31547 | ||
type F1 = (this: A) => void; | ||
type F2 = (this: B) => void; | ||
declare var f1: F1 | F2; | ||
f1(); // error | ||
~~~~ | ||
!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. | ||
!!! error TS2684: Type 'void' is not assignable to type 'A'. | ||
declare var f2: F0 | F1; | ||
f2(); // error | ||
~~~~ | ||
!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A'. | ||
|
||
interface F3 { | ||
(this: A): void; | ||
(this: B): void; | ||
} | ||
interface F4 { | ||
(this: C): void; | ||
(this: D): void; | ||
} | ||
interface F5 { | ||
(this: C): void; | ||
(this: B): void; | ||
} | ||
|
||
declare var x1: A & C & { | ||
f0: F0 | F3; | ||
f1: F1 | F3; | ||
f2: F1 | F4; | ||
f3: F3 | F4; | ||
f4: F3 | F5; | ||
} | ||
x1.f0(); | ||
x1.f1(); | ||
x1.f2(); | ||
x1.f3(); // error | ||
~~ | ||
!!! error TS2349: This expression is not callable. | ||
!!! error TS2349: Each member of the union type 'F3 | F4' has signatures, but none of those signatures are compatible with each other. | ||
x1.f4(); // error | ||
~~ | ||
!!! error TS2684: The 'this' context of type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' is not assignable to method's 'this' of type 'B'. | ||
!!! error TS2684: Property 'b' is missing in type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' but required in type 'B'. | ||
!!! related TS2728 tests/cases/conformance/types/union/unionTypeCallSignatures6.ts:2:12: 'b' is declared here. | ||
|
||
declare var x2: A & B & { | ||
f4: F3 | F5; | ||
} | ||
x2.f4(); | ||
|
||
type F6 = (this: A & B) => void; | ||
declare var f3: F1 | F6; | ||
f3(); // error | ||
~~~~ | ||
!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. | ||
!!! error TS2684: Type 'void' is not assignable to type 'A'. | ||
|
||
interface F7 { | ||
(this: A & B & C): void; | ||
(this: A & B): void; | ||
} | ||
declare var f4: F6 | F7; | ||
f4(); // error | ||
~~~~ | ||
!!! error TS2769: No overload matches this call. | ||
!!! error TS2769: Overload 1 of 2, '(this: A & B & C): void', gave the following error. | ||
!!! error TS2769: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B & C'. | ||
!!! error TS2769: Type 'void' is not assignable to type 'A'. | ||
!!! error TS2769: Overload 2 of 2, '(this: A & B): void', gave the following error. | ||
!!! error TS2769: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. | ||
!!! error TS2769: Type 'void' is not assignable to type 'A'. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
//// [unionTypeCallSignatures6.ts] | ||
type A = { a: string }; | ||
type B = { b: number }; | ||
type C = { c: string }; | ||
type D = { d: number }; | ||
type F0 = () => void; | ||
|
||
// #31547 | ||
type F1 = (this: A) => void; | ||
type F2 = (this: B) => void; | ||
declare var f1: F1 | F2; | ||
f1(); // error | ||
declare var f2: F0 | F1; | ||
f2(); // error | ||
|
||
interface F3 { | ||
(this: A): void; | ||
(this: B): void; | ||
} | ||
interface F4 { | ||
(this: C): void; | ||
(this: D): void; | ||
} | ||
interface F5 { | ||
(this: C): void; | ||
(this: B): void; | ||
} | ||
|
||
declare var x1: A & C & { | ||
f0: F0 | F3; | ||
f1: F1 | F3; | ||
f2: F1 | F4; | ||
f3: F3 | F4; | ||
f4: F3 | F5; | ||
} | ||
x1.f0(); | ||
x1.f1(); | ||
x1.f2(); | ||
x1.f3(); // error | ||
x1.f4(); // error | ||
|
||
declare var x2: A & B & { | ||
f4: F3 | F5; | ||
} | ||
x2.f4(); | ||
|
||
type F6 = (this: A & B) => void; | ||
declare var f3: F1 | F6; | ||
f3(); // error | ||
|
||
interface F7 { | ||
(this: A & B & C): void; | ||
(this: A & B): void; | ||
} | ||
declare var f4: F6 | F7; | ||
f4(); // error | ||
|
||
|
||
//// [unionTypeCallSignatures6.js] | ||
f1(); // error | ||
f2(); // error | ||
x1.f0(); | ||
x1.f1(); | ||
x1.f2(); | ||
x1.f3(); // error | ||
x1.f4(); // error | ||
x2.f4(); | ||
f3(); // error | ||
f4(); // 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.
Not a big fan of this, since it's prima facie Obviously Legal.
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.
I mean, this is the crux of the change 😅
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.
Well, it's Obviously Legal and Technically Incorrect, and in this case I think Technically Incorrect should win.