diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1b0904723dfd0..3791124a2a26e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -232,6 +232,7 @@ namespace ts { getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, agumentCount) => getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.IsForSignatureHelp), getExpandedParameters, + hasEffectiveRestParameter, getConstantValue: nodeIn => { const node = getParseTreeNode(nodeIn, canHaveConstantValue); return node ? getConstantValue(node) : undefined; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8c0091f0ba624..83bcf01742d5f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3171,6 +3171,7 @@ namespace ts { getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined; /* @internal */ getResolvedSignatureForSignatureHelp(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined; /* @internal */ getExpandedParameters(sig: Signature): ReadonlyArray; + /* @internal */ hasEffectiveRestParameter(sig: Signature): boolean; getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined; isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined; isUndefinedSymbol(symbol: Symbol): boolean; diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 70f94e95fc9f9..0c9f76acacb7f 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -566,7 +566,7 @@ namespace ts.SignatureHelp { } function itemInfoForParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo { - const isVariadic = candidateSignature.hasRestParameter; + const isVariadic = checker.hasEffectiveRestParameter(candidateSignature); const printer = createPrinter({ removeComments: true }); const typeParameterParts = mapToDisplayParts(writer => { if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { diff --git a/tests/cases/fourslash/signatureHelpCallExpressionTuples.ts b/tests/cases/fourslash/signatureHelpCallExpressionTuples.ts new file mode 100644 index 0000000000000..bcad3ccde4894 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpCallExpressionTuples.ts @@ -0,0 +1,56 @@ +/// + + +//// function fnTest(str: string, num: number) { } +//// declare function wrap(fn: (...a: A) => R) : (...a: A) => R; +//// var fnWrapped = wrap(fnTest); +//// fnWrapped/*3*/(/*1*/'', /*2*/5); +//// function fnTestVariadic (str: string, ...num: number[]) { } +//// var fnVariadicWrapped = wrap(fnTestVariadic); +//// fnVariadicWrapped/*4*/(/*5*/'', /*6*/5); +//// function fnNoParams () { } +//// var fnNoParamsWrapped = wrap(fnNoParams); +//// fnNoParamsWrapped/*7*/(/*8*/); + +verify.quickInfoAt("3", "var fnWrapped: (str: string, num: number) => void"); +verify.signatureHelp( + { + marker: "1", + text: "fnWrapped(str: string, num: number): void", + parameterCount: 2, + parameterName: "str", + parameterSpan: "str: string", + }, + { + marker: "2", + parameterName: "num", + parameterSpan: "num: number", + }, +); + +verify.quickInfoAt("4", "var fnVariadicWrapped: (str: string, ...num: number[]) => void"); +verify.signatureHelp( + { + marker: "5", + text: "fnVariadicWrapped(str: string, ...num: number[]): void", + parameterCount: 2, + parameterName: "str", + parameterSpan: "str: string", + isVariadic: true, + }, + { + marker: "6", + parameterName: "num", + parameterSpan: "...num: number[]", + isVariadic: true, + }, +); + +verify.quickInfoAt("7", "var fnNoParamsWrapped: () => void"); +verify.signatureHelp( + { + marker: "8", + text: "fnNoParamsWrapped(): void", + parameterCount: 0, + } +);