From bf19d214f32e2a30eced6b896ccc10fff01ec264 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 6 Aug 2018 16:10:10 -0700 Subject: [PATCH 1/2] Revise logic that computes the contextual type for a parameter --- src/compiler/checker.ts | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index de0da714fcf..130086ca9a2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15820,20 +15820,10 @@ namespace ts { } const contextualSignature = getContextualSignature(func); if (contextualSignature) { - const funcHasRestParameter = hasRestParameter(func); - const len = func.parameters.length - (funcHasRestParameter ? 1 : 0); - let indexOfParameter = func.parameters.indexOf(parameter); - if (getThisParameter(func) !== undefined && !contextualSignature.thisParameter) { - Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`. - indexOfParameter -= 1; - } - if (indexOfParameter < len) { - return getTypeAtPosition(contextualSignature, indexOfParameter); - } - // If last parameter is contextually rest parameter get its type - if (funcHasRestParameter && indexOfParameter === len) { - return getRestTypeAtPosition(contextualSignature, indexOfParameter); - } + const index = func.parameters.indexOf(parameter) - (getThisParameter(func) ? 1 : 0); + return parameter.dotDotDotToken && lastOrUndefined(func.parameters) === parameter ? + getRestTypeAtPosition(contextualSignature, index) : + tryGetTypeAtPosition(contextualSignature, index); } } From 9d71023b5c0613ebb3745838b5928cb9e8a7a3b7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 6 Aug 2018 16:33:21 -0700 Subject: [PATCH 2/2] Add fourslash tests --- .../fourslash/contextuallyTypedParameters.ts | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tests/cases/fourslash/contextuallyTypedParameters.ts diff --git a/tests/cases/fourslash/contextuallyTypedParameters.ts b/tests/cases/fourslash/contextuallyTypedParameters.ts new file mode 100644 index 00000000000..f600180c087 --- /dev/null +++ b/tests/cases/fourslash/contextuallyTypedParameters.ts @@ -0,0 +1,60 @@ +/// + +////declare function foo(cb: (this: any, x: number, y: string, z: boolean) => void): void; +//// +////foo(function(this, a, ...args) { +//// a/*10*/; +//// args/*11*/; +////}); +//// +////foo(function(this, a, b, ...args) { +//// a/*20*/; +//// b/*21*/; +//// args/*22*/; +////}); +//// +////foo(function(this, a, b, c, ...args) { +//// a/*30*/; +//// b/*31*/; +//// c/*32*/; +//// args/*33*/; +////}); +//// +////foo(function(a, ...args) { +//// a/*40*/; +//// args/*41*/; +////}); +//// +////foo(function(a, b, ...args) { +//// a/*50*/; +//// b/*51*/; +//// args/*52*/; +////}); +//// +////foo(function(a, b, c, ...args) { +//// a/*60*/; +//// b/*61*/; +//// c/*62*/; +//// args/*63*/; +////}); + +verify.quickInfos({ + 10: "(parameter) a: number", + 11: "(parameter) args: [string, boolean]", + 20: "(parameter) a: number", + 21: "(parameter) b: string", + 22: "(parameter) args: [boolean]", + 30: "(parameter) a: number", + 31: "(parameter) b: string", + 32: "(parameter) c: boolean", + 33: "(parameter) args: []", + 40: "(parameter) a: number", + 41: "(parameter) args: [string, boolean]", + 50: "(parameter) a: number", + 51: "(parameter) b: string", + 52: "(parameter) args: [boolean]", + 60: "(parameter) a: number", + 61: "(parameter) b: string", + 62: "(parameter) c: boolean", + 63: "(parameter) args: []", +});