Infer implied arity before inferring from 'this' argument (#39328)

* Infer implied arity before inferring from 'this' argument

* Add regression test
This commit is contained in:
Anders Hejlsberg 2020-06-29 17:38:41 -07:00 committed by GitHub
parent 9458f8acab
commit 784396ce95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 110 additions and 7 deletions

View File

@ -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) {

View File

@ -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<A extends unknown[], T> {
readonly f: (...args: A) => T;
bind<T extends unknown[], U extends unknown[], R>(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>

View File

@ -351,6 +351,16 @@ function f23<U extends string[]>(args: [...U, number]) {
let v2 = f22(["foo", "bar"]); // [string, string]
let v3 = f22(["foo", 42]); // [string]
}
// Repro from #39327
interface Desc<A extends unknown[], T> {
readonly f: (...args: A) => T;
bind<T extends unknown[], U extends unknown[], R>(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<U extends string[]>(args: [...U, number?]): void;
declare function f22<T extends unknown[] = []>(args: [...T, number]): T;
declare function f22<T extends unknown[] = []>(args: [...T]): T;
declare function f23<U extends string[]>(args: [...U, number]): void;
interface Desc<A extends unknown[], T> {
readonly f: (...args: A) => T;
bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>;
}
declare const a: Desc<[string, number, boolean], object>;
declare const b: Desc<[boolean], object>;

View File

@ -1204,3 +1204,43 @@ function f23<U extends string[]>(args: [...U, number]) {
>f22 : Symbol(f22, Decl(variadicTuples1.ts, 342, 1), Decl(variadicTuples1.ts, 344, 72))
}
// Repro from #39327
interface Desc<A extends unknown[], T> {
>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<T extends unknown[], U extends unknown[], R>(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))

View File

@ -1254,3 +1254,28 @@ function f23<U extends string[]>(args: [...U, number]) {
>42 : 42
}
// Repro from #39327
interface Desc<A extends unknown[], T> {
readonly f: (...args: A) => T;
>f : (...args: A) => T
>args : A
bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>;
>bind : <T extends unknown[], U extends unknown[], R>(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 : <T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R>
>a : Desc<[string, number, boolean], object>
>bind : <T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R>
>"" : ""
>1 : 1

View File

@ -353,3 +353,13 @@ function f23<U extends string[]>(args: [...U, number]) {
let v2 = f22(["foo", "bar"]); // [string, string]
let v3 = f22(["foo", 42]); // [string]
}
// Repro from #39327
interface Desc<A extends unknown[], T> {
readonly f: (...args: A) => T;
bind<T extends unknown[], U extends unknown[], R>(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>