Skip to content

Commit 66dba13

Browse files
authored
Fix microsoft#38482 making ThisParameterType<T> more general (microsoft#47162)
`ThisParameterType<(...args: X) => void>` expands to `(...args: X) => void extends (this: infer U, ...args: any[]) => any`. When `X` is an unresolved type parameter it is not possible to determine that `any[]` is assignable to `X`. However `never` is always assignable to `X`, so we use that instead.
1 parent 5c22729 commit 66dba13

File tree

6 files changed

+308
-2
lines changed

6 files changed

+308
-2
lines changed

src/lib/es5.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ declare var Function: FunctionConstructor;
300300
/**
301301
* Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter.
302302
*/
303-
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;
303+
type ThisParameterType<T> = T extends (this: infer U, ...args: never) => any ? U : unknown;
304304

305305
/**
306306
* Removes the 'this' parameter from a function type.

tests/baselines/reference/strictBindCallApply1.errors.txt

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,24 @@ tests/cases/conformance/functions/strictBindCallApply1.ts(70,12): error TS2345:
5858
tests/cases/conformance/functions/strictBindCallApply1.ts(71,17): error TS2322: Type 'number' is not assignable to type 'string'.
5959
tests/cases/conformance/functions/strictBindCallApply1.ts(72,12): error TS2345: Argument of type '[number, string, number]' is not assignable to parameter of type '[a: number, b: string]'.
6060
Source has 3 element(s) but target allows only 2.
61+
tests/cases/conformance/functions/strictBindCallApply1.ts(76,5): error TS2769: No overload matches this call.
62+
Overload 1 of 6, '(this: (this: 1, ...args: T) => void, thisArg: 1): (...args: T) => void', gave the following error.
63+
Argument of type '2' is not assignable to parameter of type '1'.
64+
Overload 2 of 6, '(this: (this: 1, ...args: unknown[]) => void, thisArg: 1, ...args: unknown[]): (...args: unknown[]) => void', gave the following error.
65+
The 'this' context of type '(this: 1, ...args: T) => void' is not assignable to method's 'this' of type '(this: 1, ...args: unknown[]) => void'.
66+
Types of parameters 'args' and 'args' are incompatible.
67+
Type 'unknown[]' is not assignable to type 'T'.
68+
'unknown[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'unknown[]'.
69+
tests/cases/conformance/functions/strictBindCallApply1.ts(81,5): error TS2769: No overload matches this call.
70+
Overload 1 of 6, '(this: (this: 1, ...args: T extends 1 ? [unknown] : [unknown, unknown]) => void, thisArg: 1): (...args: T extends 1 ? [unknown] : [unknown, unknown]) => void', gave the following error.
71+
Argument of type '2' is not assignable to parameter of type '1'.
72+
Overload 2 of 6, '(this: (this: 1, ...args: unknown[]) => void, thisArg: 1, ...args: unknown[]): (...args: unknown[]) => void', gave the following error.
73+
The 'this' context of type '(this: 1, ...args: T extends 1 ? [unknown] : [unknown, unknown]) => void' is not assignable to method's 'this' of type '(this: 1, ...args: unknown[]) => void'.
74+
Types of parameters 'args' and 'args' are incompatible.
75+
Type 'unknown[]' is not assignable to type 'T extends 1 ? [unknown] : [unknown, unknown]'.
6176

6277

63-
==== tests/cases/conformance/functions/strictBindCallApply1.ts (24 errors) ====
78+
==== tests/cases/conformance/functions/strictBindCallApply1.ts (26 errors) ====
6479
declare function foo(a: number, b: string): string;
6580

6681
declare function overloaded(s: string): number;
@@ -217,4 +232,48 @@ tests/cases/conformance/functions/strictBindCallApply1.ts(72,12): error TS2345:
217232
~~~~~~~~~~~~~~~~~
218233
!!! error TS2345: Argument of type '[number, string, number]' is not assignable to parameter of type '[a: number, b: string]'.
219234
!!! error TS2345: Source has 3 element(s) but target allows only 2.
235+
236+
function bar<T extends unknown[]>(callback: (this: 1, ...args: T) => void) {
237+
callback.bind(1);
238+
callback.bind(2); // Error
239+
~~~~~~~~~~~~~~~~
240+
!!! error TS2769: No overload matches this call.
241+
!!! error TS2769: Overload 1 of 6, '(this: (this: 1, ...args: T) => void, thisArg: 1): (...args: T) => void', gave the following error.
242+
!!! error TS2769: Argument of type '2' is not assignable to parameter of type '1'.
243+
!!! error TS2769: Overload 2 of 6, '(this: (this: 1, ...args: unknown[]) => void, thisArg: 1, ...args: unknown[]): (...args: unknown[]) => void', gave the following error.
244+
!!! error TS2769: The 'this' context of type '(this: 1, ...args: T) => void' is not assignable to method's 'this' of type '(this: 1, ...args: unknown[]) => void'.
245+
!!! error TS2769: Types of parameters 'args' and 'args' are incompatible.
246+
!!! error TS2769: Type 'unknown[]' is not assignable to type 'T'.
247+
!!! error TS2769: 'unknown[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'unknown[]'.
248+
}
249+
250+
function baz<T extends 1 | 2>(callback: (this: 1, ...args: T extends 1 ? [unknown] : [unknown, unknown]) => void) {
251+
callback.bind(1);
252+
callback.bind(2); // Error
253+
~~~~~~~~~~~~~~~~
254+
!!! error TS2769: No overload matches this call.
255+
!!! error TS2769: Overload 1 of 6, '(this: (this: 1, ...args: T extends 1 ? [unknown] : [unknown, unknown]) => void, thisArg: 1): (...args: T extends 1 ? [unknown] : [unknown, unknown]) => void', gave the following error.
256+
!!! error TS2769: Argument of type '2' is not assignable to parameter of type '1'.
257+
!!! error TS2769: Overload 2 of 6, '(this: (this: 1, ...args: unknown[]) => void, thisArg: 1, ...args: unknown[]): (...args: unknown[]) => void', gave the following error.
258+
!!! error TS2769: The 'this' context of type '(this: 1, ...args: T extends 1 ? [unknown] : [unknown, unknown]) => void' is not assignable to method's 'this' of type '(this: 1, ...args: unknown[]) => void'.
259+
!!! error TS2769: Types of parameters 'args' and 'args' are incompatible.
260+
!!! error TS2769: Type 'unknown[]' is not assignable to type 'T extends 1 ? [unknown] : [unknown, unknown]'.
261+
}
262+
263+
// Repro from #32964
264+
class Foo<T extends unknown[]> {
265+
constructor() {
266+
this.fn.bind(this);
267+
}
268+
269+
fn(...args: T): void {}
270+
}
271+
272+
class Bar<T extends 1 | 2> {
273+
constructor() {
274+
this.fn.bind(this);
275+
}
276+
277+
fn(...args: T extends 1 ? [unknown] : [unknown, unknown]) {}
278+
}
220279

tests/baselines/reference/strictBindCallApply1.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,33 @@ C.apply(c, [10, "hello"]);
7171
C.apply(c, [10]); // Error
7272
C.apply(c, [10, 20]); // Error
7373
C.apply(c, [10, "hello", 30]); // Error
74+
75+
function bar<T extends unknown[]>(callback: (this: 1, ...args: T) => void) {
76+
callback.bind(1);
77+
callback.bind(2); // Error
78+
}
79+
80+
function baz<T extends 1 | 2>(callback: (this: 1, ...args: T extends 1 ? [unknown] : [unknown, unknown]) => void) {
81+
callback.bind(1);
82+
callback.bind(2); // Error
83+
}
84+
85+
// Repro from #32964
86+
class Foo<T extends unknown[]> {
87+
constructor() {
88+
this.fn.bind(this);
89+
}
90+
91+
fn(...args: T): void {}
92+
}
93+
94+
class Bar<T extends 1 | 2> {
95+
constructor() {
96+
this.fn.bind(this);
97+
}
98+
99+
fn(...args: T extends 1 ? [unknown] : [unknown, unknown]) {}
100+
}
74101

75102

76103
//// [strictBindCallApply1.js]
@@ -126,3 +153,36 @@ C.apply(c, [10, "hello"]);
126153
C.apply(c, [10]); // Error
127154
C.apply(c, [10, 20]); // Error
128155
C.apply(c, [10, "hello", 30]); // Error
156+
function bar(callback) {
157+
callback.bind(1);
158+
callback.bind(2); // Error
159+
}
160+
function baz(callback) {
161+
callback.bind(1);
162+
callback.bind(2); // Error
163+
}
164+
// Repro from #32964
165+
var Foo = /** @class */ (function () {
166+
function Foo() {
167+
this.fn.bind(this);
168+
}
169+
Foo.prototype.fn = function () {
170+
var args = [];
171+
for (var _i = 0; _i < arguments.length; _i++) {
172+
args[_i] = arguments[_i];
173+
}
174+
};
175+
return Foo;
176+
}());
177+
var Bar = /** @class */ (function () {
178+
function Bar() {
179+
this.fn.bind(this);
180+
}
181+
Bar.prototype.fn = function () {
182+
var args = [];
183+
for (var _i = 0; _i < arguments.length; _i++) {
184+
args[_i] = arguments[_i];
185+
}
186+
};
187+
return Bar;
188+
}());

tests/baselines/reference/strictBindCallApply1.symbols

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,82 @@ C.apply(c, [10, "hello", 30]); // Error
388388
>apply : Symbol(NewableFunction.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
389389
>c : Symbol(c, Decl(strictBindCallApply1.ts, 34, 11))
390390

391+
function bar<T extends unknown[]>(callback: (this: 1, ...args: T) => void) {
392+
>bar : Symbol(bar, Decl(strictBindCallApply1.ts, 71, 30))
393+
>T : Symbol(T, Decl(strictBindCallApply1.ts, 73, 13))
394+
>callback : Symbol(callback, Decl(strictBindCallApply1.ts, 73, 34))
395+
>this : Symbol(this, Decl(strictBindCallApply1.ts, 73, 45))
396+
>args : Symbol(args, Decl(strictBindCallApply1.ts, 73, 53))
397+
>T : Symbol(T, Decl(strictBindCallApply1.ts, 73, 13))
398+
399+
callback.bind(1);
400+
>callback.bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
401+
>callback : Symbol(callback, Decl(strictBindCallApply1.ts, 73, 34))
402+
>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
403+
404+
callback.bind(2); // Error
405+
>callback.bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
406+
>callback : Symbol(callback, Decl(strictBindCallApply1.ts, 73, 34))
407+
>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
408+
}
409+
410+
function baz<T extends 1 | 2>(callback: (this: 1, ...args: T extends 1 ? [unknown] : [unknown, unknown]) => void) {
411+
>baz : Symbol(baz, Decl(strictBindCallApply1.ts, 76, 1))
412+
>T : Symbol(T, Decl(strictBindCallApply1.ts, 78, 13))
413+
>callback : Symbol(callback, Decl(strictBindCallApply1.ts, 78, 30))
414+
>this : Symbol(this, Decl(strictBindCallApply1.ts, 78, 41))
415+
>args : Symbol(args, Decl(strictBindCallApply1.ts, 78, 49))
416+
>T : Symbol(T, Decl(strictBindCallApply1.ts, 78, 13))
417+
418+
callback.bind(1);
419+
>callback.bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
420+
>callback : Symbol(callback, Decl(strictBindCallApply1.ts, 78, 30))
421+
>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
422+
423+
callback.bind(2); // Error
424+
>callback.bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
425+
>callback : Symbol(callback, Decl(strictBindCallApply1.ts, 78, 30))
426+
>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
427+
}
428+
429+
// Repro from #32964
430+
class Foo<T extends unknown[]> {
431+
>Foo : Symbol(Foo, Decl(strictBindCallApply1.ts, 81, 1))
432+
>T : Symbol(T, Decl(strictBindCallApply1.ts, 84, 10))
433+
434+
constructor() {
435+
this.fn.bind(this);
436+
>this.fn.bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
437+
>this.fn : Symbol(Foo.fn, Decl(strictBindCallApply1.ts, 87, 5))
438+
>this : Symbol(Foo, Decl(strictBindCallApply1.ts, 81, 1))
439+
>fn : Symbol(Foo.fn, Decl(strictBindCallApply1.ts, 87, 5))
440+
>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
441+
>this : Symbol(Foo, Decl(strictBindCallApply1.ts, 81, 1))
442+
}
443+
444+
fn(...args: T): void {}
445+
>fn : Symbol(Foo.fn, Decl(strictBindCallApply1.ts, 87, 5))
446+
>args : Symbol(args, Decl(strictBindCallApply1.ts, 89, 7))
447+
>T : Symbol(T, Decl(strictBindCallApply1.ts, 84, 10))
448+
}
449+
450+
class Bar<T extends 1 | 2> {
451+
>Bar : Symbol(Bar, Decl(strictBindCallApply1.ts, 90, 1))
452+
>T : Symbol(T, Decl(strictBindCallApply1.ts, 92, 10))
453+
454+
constructor() {
455+
this.fn.bind(this);
456+
>this.fn.bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
457+
>this.fn : Symbol(Bar.fn, Decl(strictBindCallApply1.ts, 95, 5))
458+
>this : Symbol(Bar, Decl(strictBindCallApply1.ts, 90, 1))
459+
>fn : Symbol(Bar.fn, Decl(strictBindCallApply1.ts, 95, 5))
460+
>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more)
461+
>this : Symbol(Bar, Decl(strictBindCallApply1.ts, 90, 1))
462+
}
463+
464+
fn(...args: T extends 1 ? [unknown] : [unknown, unknown]) {}
465+
>fn : Symbol(Bar.fn, Decl(strictBindCallApply1.ts, 95, 5))
466+
>args : Symbol(args, Decl(strictBindCallApply1.ts, 97, 7))
467+
>T : Symbol(T, Decl(strictBindCallApply1.ts, 92, 10))
468+
}
469+

0 commit comments

Comments
 (0)