diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 649979e4120..4432ad672a0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15827,20 +15827,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); } } 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: []", +});