Skip to content

Commit 784396c

Browse files
authored
Infer implied arity before inferring from 'this' argument (microsoft#39328)
* Infer implied arity before inferring from 'this' argument * Add regression test
1 parent 9458f8a commit 784396c

File tree

6 files changed

+110
-7
lines changed

6 files changed

+110
-7
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25773,13 +25773,6 @@ namespace ts {
2577325773
}
2577425774
}
2577525775

25776-
const thisType = getThisTypeOfSignature(signature);
25777-
if (thisType) {
25778-
const thisArgumentNode = getThisArgumentOfCall(node);
25779-
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
25780-
inferTypes(context.inferences, thisArgumentType, thisType);
25781-
}
25782-
2578325776
const restType = getNonArrayRestType(signature);
2578425777
const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
2578525778
if (restType && restType.flags & TypeFlags.TypeParameter) {
@@ -25788,6 +25781,14 @@ namespace ts {
2578825781
info.impliedArity = findIndex(args, isSpreadArgument, argCount) < 0 ? args.length - argCount : undefined;
2578925782
}
2579025783
}
25784+
25785+
const thisType = getThisTypeOfSignature(signature);
25786+
if (thisType) {
25787+
const thisArgumentNode = getThisArgumentOfCall(node);
25788+
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
25789+
inferTypes(context.inferences, thisArgumentType, thisType);
25790+
}
25791+
2579125792
for (let i = 0; i < argCount; i++) {
2579225793
const arg = args[i];
2579325794
if (arg.kind !== SyntaxKind.OmittedExpression) {

tests/baselines/reference/variadicTuples1.errors.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,4 +463,14 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(342,19): error TS2322: Ty
463463
let v2 = f22(["foo", "bar"]); // [string, string]
464464
let v3 = f22(["foo", 42]); // [string]
465465
}
466+
467+
// Repro from #39327
468+
469+
interface Desc<A extends unknown[], T> {
470+
readonly f: (...args: A) => T;
471+
bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>;
472+
}
473+
474+
declare const a: Desc<[string, number, boolean], object>;
475+
const b = a.bind("", 1); // Desc<[boolean], object>
466476

tests/baselines/reference/variadicTuples1.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,16 @@ function f23<U extends string[]>(args: [...U, number]) {
351351
let v2 = f22(["foo", "bar"]); // [string, string]
352352
let v3 = f22(["foo", 42]); // [string]
353353
}
354+
355+
// Repro from #39327
356+
357+
interface Desc<A extends unknown[], T> {
358+
readonly f: (...args: A) => T;
359+
bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>;
360+
}
361+
362+
declare const a: Desc<[string, number, boolean], object>;
363+
const b = a.bind("", 1); // Desc<[boolean], object>
354364

355365

356366
//// [variadicTuples1.js]
@@ -557,6 +567,7 @@ function f23(args) {
557567
var v2 = f22(["foo", "bar"]); // [string, string]
558568
var v3 = f22(["foo", 42]); // [string]
559569
}
570+
var b = a.bind("", 1); // Desc<[boolean], object>
560571

561572

562573
//// [variadicTuples1.d.ts]
@@ -703,3 +714,9 @@ declare function f21<U extends string[]>(args: [...U, number?]): void;
703714
declare function f22<T extends unknown[] = []>(args: [...T, number]): T;
704715
declare function f22<T extends unknown[] = []>(args: [...T]): T;
705716
declare function f23<U extends string[]>(args: [...U, number]): void;
717+
interface Desc<A extends unknown[], T> {
718+
readonly f: (...args: A) => T;
719+
bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>;
720+
}
721+
declare const a: Desc<[string, number, boolean], object>;
722+
declare const b: Desc<[boolean], object>;

tests/baselines/reference/variadicTuples1.symbols

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,3 +1204,43 @@ function f23<U extends string[]>(args: [...U, number]) {
12041204
>f22 : Symbol(f22, Decl(variadicTuples1.ts, 342, 1), Decl(variadicTuples1.ts, 344, 72))
12051205
}
12061206

1207+
// Repro from #39327
1208+
1209+
interface Desc<A extends unknown[], T> {
1210+
>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1))
1211+
>A : Symbol(A, Decl(variadicTuples1.ts, 355, 15))
1212+
>T : Symbol(T, Decl(variadicTuples1.ts, 355, 35))
1213+
1214+
readonly f: (...args: A) => T;
1215+
>f : Symbol(Desc.f, Decl(variadicTuples1.ts, 355, 40))
1216+
>args : Symbol(args, Decl(variadicTuples1.ts, 356, 17))
1217+
>A : Symbol(A, Decl(variadicTuples1.ts, 355, 15))
1218+
>T : Symbol(T, Decl(variadicTuples1.ts, 355, 35))
1219+
1220+
bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>;
1221+
>bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34))
1222+
>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9))
1223+
>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29))
1224+
>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50))
1225+
>this : Symbol(this, Decl(variadicTuples1.ts, 357, 54))
1226+
>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1))
1227+
>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9))
1228+
>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29))
1229+
>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50))
1230+
>args : Symbol(args, Decl(variadicTuples1.ts, 357, 82))
1231+
>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9))
1232+
>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1))
1233+
>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29))
1234+
>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50))
1235+
}
1236+
1237+
declare const a: Desc<[string, number, boolean], object>;
1238+
>a : Symbol(a, Decl(variadicTuples1.ts, 360, 13))
1239+
>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1))
1240+
1241+
const b = a.bind("", 1); // Desc<[boolean], object>
1242+
>b : Symbol(b, Decl(variadicTuples1.ts, 361, 5))
1243+
>a.bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34))
1244+
>a : Symbol(a, Decl(variadicTuples1.ts, 360, 13))
1245+
>bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34))
1246+

tests/baselines/reference/variadicTuples1.types

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,3 +1254,28 @@ function f23<U extends string[]>(args: [...U, number]) {
12541254
>42 : 42
12551255
}
12561256

1257+
// Repro from #39327
1258+
1259+
interface Desc<A extends unknown[], T> {
1260+
readonly f: (...args: A) => T;
1261+
>f : (...args: A) => T
1262+
>args : A
1263+
1264+
bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>;
1265+
>bind : <T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R>
1266+
>this : Desc<[...T, ...U], R>
1267+
>args : T
1268+
}
1269+
1270+
declare const a: Desc<[string, number, boolean], object>;
1271+
>a : Desc<[string, number, boolean], object>
1272+
1273+
const b = a.bind("", 1); // Desc<[boolean], object>
1274+
>b : Desc<[boolean], object>
1275+
>a.bind("", 1) : Desc<[boolean], object>
1276+
>a.bind : <T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R>
1277+
>a : Desc<[string, number, boolean], object>
1278+
>bind : <T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R>
1279+
>"" : ""
1280+
>1 : 1
1281+

tests/cases/conformance/types/tuple/variadicTuples1.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,13 @@ function f23<U extends string[]>(args: [...U, number]) {
353353
let v2 = f22(["foo", "bar"]); // [string, string]
354354
let v3 = f22(["foo", 42]); // [string]
355355
}
356+
357+
// Repro from #39327
358+
359+
interface Desc<A extends unknown[], T> {
360+
readonly f: (...args: A) => T;
361+
bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>;
362+
}
363+
364+
declare const a: Desc<[string, number, boolean], object>;
365+
const b = a.bind("", 1); // Desc<[boolean], object>

0 commit comments

Comments
 (0)