Add simple version of chooseOverload for common case of single non-generic signature (#17589)

* Add simple version of `chooseOverload` for common case of single non-generic signature

* Use a single function
This commit is contained in:
Andy 2017-08-09 14:41:38 -07:00 committed by GitHub
parent 37b20ee670
commit e1ba65ae64
6 changed files with 115 additions and 5 deletions

View File

@ -15705,9 +15705,10 @@ namespace ts {
//
// For a decorator, no arguments are susceptible to contextual typing due to the fact
// decorators are applied to a declaration by the emitter, and not to an expression.
const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
let excludeArgument: boolean[];
let excludeCount = 0;
if (!isDecorator) {
if (!isDecorator && !isSingleNonGenericCandidate) {
// We do not need to call `getEffectiveArgumentCount` here as it only
// applies when calculating the number of arguments for a decorator.
for (let i = isTaggedTemplate ? 1 : 0; i < args.length; i++) {
@ -15860,6 +15861,19 @@ namespace ts {
function chooseOverload(candidates: Signature[], relation: Map<RelationComparisonResult>, signatureHelpTrailingComma = false) {
candidateForArgumentError = undefined;
candidateForTypeArgumentError = undefined;
if (isSingleNonGenericCandidate) {
const candidate = candidates[0];
if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
return undefined;
}
if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
candidateForArgumentError = candidate;
return undefined;
}
return candidate;
}
for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
const originalCandidate = candidates[candidateIndex];
if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) {
@ -15907,7 +15921,6 @@ namespace ts {
return undefined;
}
}
function getLongestCandidateIndex(candidates: Signature[], argsCount: number): number {

View File

@ -0,0 +1,19 @@
//// [contextualTypingFunctionReturningFunction.ts]
interface I {
a(s: string): void;
b(): (n: number) => void;
}
declare function f(i: I): void;
f({
a: s => {},
b: () => n => {},
});
//// [contextualTypingFunctionReturningFunction.js]
f({
a: function (s) { },
b: function () { return function (n) { }; }
});

View File

@ -0,0 +1,31 @@
=== tests/cases/compiler/contextualTypingFunctionReturningFunction.ts ===
interface I {
>I : Symbol(I, Decl(contextualTypingFunctionReturningFunction.ts, 0, 0))
a(s: string): void;
>a : Symbol(I.a, Decl(contextualTypingFunctionReturningFunction.ts, 0, 13))
>s : Symbol(s, Decl(contextualTypingFunctionReturningFunction.ts, 1, 3))
b(): (n: number) => void;
>b : Symbol(I.b, Decl(contextualTypingFunctionReturningFunction.ts, 1, 20))
>n : Symbol(n, Decl(contextualTypingFunctionReturningFunction.ts, 2, 7))
}
declare function f(i: I): void;
>f : Symbol(f, Decl(contextualTypingFunctionReturningFunction.ts, 3, 1))
>i : Symbol(i, Decl(contextualTypingFunctionReturningFunction.ts, 5, 19))
>I : Symbol(I, Decl(contextualTypingFunctionReturningFunction.ts, 0, 0))
f({
>f : Symbol(f, Decl(contextualTypingFunctionReturningFunction.ts, 3, 1))
a: s => {},
>a : Symbol(a, Decl(contextualTypingFunctionReturningFunction.ts, 7, 3))
>s : Symbol(s, Decl(contextualTypingFunctionReturningFunction.ts, 8, 3))
b: () => n => {},
>b : Symbol(b, Decl(contextualTypingFunctionReturningFunction.ts, 8, 12))
>n : Symbol(n, Decl(contextualTypingFunctionReturningFunction.ts, 9, 9))
});

View File

@ -0,0 +1,36 @@
=== tests/cases/compiler/contextualTypingFunctionReturningFunction.ts ===
interface I {
>I : I
a(s: string): void;
>a : (s: string) => void
>s : string
b(): (n: number) => void;
>b : () => (n: number) => void
>n : number
}
declare function f(i: I): void;
>f : (i: I) => void
>i : I
>I : I
f({
>f({ a: s => {}, b: () => n => {},}) : void
>f : (i: I) => void
>{ a: s => {}, b: () => n => {},} : { a: (s: string) => void; b: () => (n: number) => void; }
a: s => {},
>a : (s: string) => void
>s => {} : (s: string) => void
>s : string
b: () => n => {},
>b : () => (n: number) => void
>() => n => {} : () => (n: number) => void
>n => {} : (n: number) => void
>n : number
});

View File

@ -25,7 +25,7 @@ class TestController {
>this.m : (def: IDef) => void
>this : this
>m : (def: IDef) => void
>{ p1: e => { }, p2: () => { return vvvvvvvvv => this; }, } : { p1: (e: string) => void; p2: () => {}; }
>{ p1: e => { }, p2: () => { return vvvvvvvvv => this; }, } : { p1: (e: string) => void; p2: () => (vvvvvvvvv: number) => this; }
p1: e => { },
>p1 : (e: string) => void
@ -33,8 +33,8 @@ class TestController {
>e : string
p2: () => { return vvvvvvvvv => this; },
>p2 : () => {}
>() => { return vvvvvvvvv => this; } : () => {}
>p2 : () => (vvvvvvvvv: number) => this
>() => { return vvvvvvvvv => this; } : () => (vvvvvvvvv: number) => this
>vvvvvvvvv => this : (vvvvvvvvv: number) => this
>vvvvvvvvv : number
>this : this

View File

@ -0,0 +1,11 @@
interface I {
a(s: string): void;
b(): (n: number) => void;
}
declare function f(i: I): void;
f({
a: s => {},
b: () => n => {},
});