diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3ad58313c4cc8..949af06d12167 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25773,13 +25773,6 @@ namespace ts { } } - const thisType = getThisTypeOfSignature(signature); - if (thisType) { - const thisArgumentNode = getThisArgumentOfCall(node); - const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType; - inferTypes(context.inferences, thisArgumentType, thisType); - } - const restType = getNonArrayRestType(signature); const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length; if (restType && restType.flags & TypeFlags.TypeParameter) { @@ -25788,6 +25781,14 @@ namespace ts { info.impliedArity = findIndex(args, isSpreadArgument, argCount) < 0 ? args.length - argCount : undefined; } } + + const thisType = getThisTypeOfSignature(signature); + if (thisType) { + const thisArgumentNode = getThisArgumentOfCall(node); + const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType; + inferTypes(context.inferences, thisArgumentType, thisType); + } + for (let i = 0; i < argCount; i++) { const arg = args[i]; if (arg.kind !== SyntaxKind.OmittedExpression) { diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index eac8f5ef32a5f..8468cabd7119b 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -463,4 +463,14 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(342,19): error TS2322: Ty let v2 = f22(["foo", "bar"]); // [string, string] let v3 = f22(["foo", 42]); // [string] } + + // Repro from #39327 + + interface Desc { + readonly f: (...args: A) => T; + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; + } + + declare const a: Desc<[string, number, boolean], object>; + const b = a.bind("", 1); // Desc<[boolean], object> \ No newline at end of file diff --git a/tests/baselines/reference/variadicTuples1.js b/tests/baselines/reference/variadicTuples1.js index f7d388ea5ae86..be8cf4838eea3 100644 --- a/tests/baselines/reference/variadicTuples1.js +++ b/tests/baselines/reference/variadicTuples1.js @@ -351,6 +351,16 @@ function f23(args: [...U, number]) { let v2 = f22(["foo", "bar"]); // [string, string] let v3 = f22(["foo", 42]); // [string] } + +// Repro from #39327 + +interface Desc { + readonly f: (...args: A) => T; + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +} + +declare const a: Desc<[string, number, boolean], object>; +const b = a.bind("", 1); // Desc<[boolean], object> //// [variadicTuples1.js] @@ -557,6 +567,7 @@ function f23(args) { var v2 = f22(["foo", "bar"]); // [string, string] var v3 = f22(["foo", 42]); // [string] } +var b = a.bind("", 1); // Desc<[boolean], object> //// [variadicTuples1.d.ts] @@ -703,3 +714,9 @@ declare function f21(args: [...U, number?]): void; declare function f22(args: [...T, number]): T; declare function f22(args: [...T]): T; declare function f23(args: [...U, number]): void; +interface Desc { + readonly f: (...args: A) => T; + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +} +declare const a: Desc<[string, number, boolean], object>; +declare const b: Desc<[boolean], object>; diff --git a/tests/baselines/reference/variadicTuples1.symbols b/tests/baselines/reference/variadicTuples1.symbols index 0f6c900fb6cdf..e7c9db73fc13f 100644 --- a/tests/baselines/reference/variadicTuples1.symbols +++ b/tests/baselines/reference/variadicTuples1.symbols @@ -1204,3 +1204,43 @@ function f23(args: [...U, number]) { >f22 : Symbol(f22, Decl(variadicTuples1.ts, 342, 1), Decl(variadicTuples1.ts, 344, 72)) } +// Repro from #39327 + +interface Desc { +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1)) +>A : Symbol(A, Decl(variadicTuples1.ts, 355, 15)) +>T : Symbol(T, Decl(variadicTuples1.ts, 355, 35)) + + readonly f: (...args: A) => T; +>f : Symbol(Desc.f, Decl(variadicTuples1.ts, 355, 40)) +>args : Symbol(args, Decl(variadicTuples1.ts, 356, 17)) +>A : Symbol(A, Decl(variadicTuples1.ts, 355, 15)) +>T : Symbol(T, Decl(variadicTuples1.ts, 355, 35)) + + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +>bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34)) +>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9)) +>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50)) +>this : Symbol(this, Decl(variadicTuples1.ts, 357, 54)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9)) +>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50)) +>args : Symbol(args, Decl(variadicTuples1.ts, 357, 82)) +>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1)) +>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50)) +} + +declare const a: Desc<[string, number, boolean], object>; +>a : Symbol(a, Decl(variadicTuples1.ts, 360, 13)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1)) + +const b = a.bind("", 1); // Desc<[boolean], object> +>b : Symbol(b, Decl(variadicTuples1.ts, 361, 5)) +>a.bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34)) +>a : Symbol(a, Decl(variadicTuples1.ts, 360, 13)) +>bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34)) + diff --git a/tests/baselines/reference/variadicTuples1.types b/tests/baselines/reference/variadicTuples1.types index 0c24e873ef8b5..6882761339374 100644 --- a/tests/baselines/reference/variadicTuples1.types +++ b/tests/baselines/reference/variadicTuples1.types @@ -1254,3 +1254,28 @@ function f23(args: [...U, number]) { >42 : 42 } +// Repro from #39327 + +interface Desc { + readonly f: (...args: A) => T; +>f : (...args: A) => T +>args : A + + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +>bind : (this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R> +>this : Desc<[...T, ...U], R> +>args : T +} + +declare const a: Desc<[string, number, boolean], object>; +>a : Desc<[string, number, boolean], object> + +const b = a.bind("", 1); // Desc<[boolean], object> +>b : Desc<[boolean], object> +>a.bind("", 1) : Desc<[boolean], object> +>a.bind : (this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R> +>a : Desc<[string, number, boolean], object> +>bind : (this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R> +>"" : "" +>1 : 1 + diff --git a/tests/cases/conformance/types/tuple/variadicTuples1.ts b/tests/cases/conformance/types/tuple/variadicTuples1.ts index 07732a0a5a726..e6562f20ccc4c 100644 --- a/tests/cases/conformance/types/tuple/variadicTuples1.ts +++ b/tests/cases/conformance/types/tuple/variadicTuples1.ts @@ -353,3 +353,13 @@ function f23(args: [...U, number]) { let v2 = f22(["foo", "bar"]); // [string, string] let v3 = f22(["foo", 42]); // [string] } + +// Repro from #39327 + +interface Desc { + readonly f: (...args: A) => T; + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +} + +declare const a: Desc<[string, number, boolean], object>; +const b = a.bind("", 1); // Desc<[boolean], object>