Skip to content

Commit 99bec50

Browse files
authored
Use mapped rest type member when expanding rest parameter names (microsoft#39317)
* Use mapped rest type member when expanding rest parameter names * Add test for microsoft#39228 which is also fixed by parameters having unique names
1 parent ee5c3fa commit 99bec50

6 files changed

+137
-4
lines changed

src/compiler/checker.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -9781,7 +9781,7 @@ namespace ts {
97819781
const restParams = map(elementTypes, (t, i) => {
97829782
// Lookup the label from the individual tuple passed in before falling back to the signature `rest` parameter name
97839783
const tupleLabelName = !!associatedNames && getTupleElementLabel(associatedNames[i]);
9784-
const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i);
9784+
const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i, restType);
97859785
const flags = restType.target.elementFlags[i];
97869786
const checkFlags = flags & ElementFlags.Variable ? CheckFlags.RestParameter :
97879787
flags & ElementFlags.Optional ? CheckFlags.OptionalParameter : 0;
@@ -27708,13 +27708,13 @@ namespace ts {
2770827708
return d.name.escapedText;
2770927709
}
2771027710

27711-
function getParameterNameAtPosition(signature: Signature, pos: number) {
27711+
function getParameterNameAtPosition(signature: Signature, pos: number, overrideRestType?: Type) {
2771227712
const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
2771327713
if (pos < paramCount) {
2771427714
return signature.parameters[pos].escapedName;
2771527715
}
2771627716
const restParameter = signature.parameters[paramCount] || unknownSymbol;
27717-
const restType = getTypeOfSymbol(restParameter);
27717+
const restType = overrideRestType || getTypeOfSymbol(restParameter);
2771827718
if (isTupleType(restType)) {
2771927719
const associatedNames = (<TupleType>(<TypeReference>restType).target).labeledElementDeclarations;
2772027720
const index = pos - paramCount;

src/harness/fourslashImpl.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ namespace FourSlash {
14261426
this.raiseError("Could not get a help signature");
14271427
}
14281428

1429-
const selectedItem = help.items[help.selectedItemIndex];
1429+
const selectedItem = help.items[options.overrideSelectedItemIndex ?? help.selectedItemIndex];
14301430
// Argument index may exceed number of parameters
14311431
const currentParameter = selectedItem.parameters[help.argumentIndex] as ts.SignatureHelpParameter | undefined;
14321432

@@ -1478,6 +1478,7 @@ namespace FourSlash {
14781478
"isVariadic",
14791479
"tags",
14801480
"argumentCount",
1481+
"overrideSelectedItemIndex"
14811482
];
14821483
for (const key in options) {
14831484
if (!ts.contains(allKeys, key)) {

src/harness/fourslashInterfaceImpl.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,7 @@ namespace FourSlashInterface {
15331533
/** @default ts.emptyArray */
15341534
readonly tags?: readonly ts.JSDocTagInfo[];
15351535
readonly triggerReason?: ts.SignatureHelpTriggerReason;
1536+
readonly overrideSelectedItemIndex?: number;
15361537
}
15371538

15381539
export interface VerifyNavigateToOptions {

tests/cases/fourslash/fourslash.ts

+1
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,7 @@ declare namespace FourSlashInterface {
644644
isVariadic?: boolean;
645645
tags?: ReadonlyArray<JSDocTagInfo>;
646646
triggerReason?: SignatureHelpTriggerReason;
647+
overrideSelectedItemIndex?: number;
647648
}
648649

649650
export type SignatureHelpTriggerReason =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////export function complex(item: string, another: string, ...rest: [] | [object, (err: Error) => void] | [(err: Error) => void, ...object[]]) {
4+
////
5+
////}
6+
////
7+
////complex(/*1*/);
8+
////complex("ok", "ok", /*2*/);
9+
////complex("ok", "ok", e => void e, {}, /*3*/);
10+
11+
verify.signatureHelp(
12+
{
13+
marker: "1",
14+
text: "complex(item: string, another: string): void",
15+
overloadsCount: 3,
16+
parameterCount: 2,
17+
parameterName: "item",
18+
parameterSpan: "item: string",
19+
isVariadic: false,
20+
},
21+
{
22+
marker: "2",
23+
text: "complex(item: string, another: string, rest_0: object, rest_1: (err: Error) => void): void",
24+
overloadsCount: 3,
25+
parameterCount: 4,
26+
parameterName: "rest_0",
27+
parameterSpan: "rest_0: object",
28+
isVariadic: false,
29+
},
30+
{
31+
marker: "3",
32+
text: "complex(item: string, another: string, rest_0: (err: Error) => void, ...rest_1: object[]): void",
33+
overloadsCount: 3,
34+
isVariadic: true,
35+
},
36+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////function foo(...args: [string, string] | [number, string, string]
4+
////) {
5+
////
6+
////}
7+
////
8+
////foo(123/*1*/,)
9+
////foo(""/*2*/, ""/*3*/)
10+
////foo(123/*4*/, ""/*5*/, )
11+
////foo(123/*6*/, ""/*7*/, ""/*8*/)
12+
13+
verify.signatureHelp(
14+
{
15+
marker: "1",
16+
text: "foo(args_0: number, args_1: string, args_2: string): void",
17+
overloadsCount: 2,
18+
parameterCount: 3,
19+
parameterName: "args_0",
20+
parameterSpan: "args_0: number",
21+
isVariadic: false,
22+
overrideSelectedItemIndex: 1
23+
},
24+
{
25+
marker: "2",
26+
text: "foo(args_0: string, args_1: string): void",
27+
overloadsCount: 2,
28+
parameterCount: 2,
29+
parameterName: "args_0",
30+
parameterSpan: "args_0: string",
31+
isVariadic: false,
32+
overrideSelectedItemIndex: 0
33+
},
34+
{
35+
marker: "3",
36+
text: "foo(args_0: string, args_1: string): void",
37+
overloadsCount: 2,
38+
parameterCount: 2,
39+
parameterName: "args_1",
40+
parameterSpan: "args_1: string",
41+
isVariadic: false,
42+
overrideSelectedItemIndex: 0
43+
},
44+
{
45+
marker: "4",
46+
text: "foo(args_0: number, args_1: string, args_2: string): void",
47+
overloadsCount: 2,
48+
parameterCount: 3,
49+
parameterName: "args_0",
50+
parameterSpan: "args_0: number",
51+
isVariadic: false,
52+
overrideSelectedItemIndex: 1
53+
},
54+
{
55+
marker: "5",
56+
text: "foo(args_0: number, args_1: string, args_2: string): void",
57+
overloadsCount: 2,
58+
parameterCount: 3,
59+
parameterName: "args_1",
60+
parameterSpan: "args_1: string",
61+
isVariadic: false,
62+
overrideSelectedItemIndex: 1
63+
},
64+
{
65+
marker: "6",
66+
text: "foo(args_0: number, args_1: string, args_2: string): void",
67+
overloadsCount: 2,
68+
parameterCount: 3,
69+
parameterName: "args_0",
70+
parameterSpan: "args_0: number",
71+
isVariadic: false,
72+
overrideSelectedItemIndex: 1
73+
},
74+
{
75+
marker: "7",
76+
text: "foo(args_0: number, args_1: string, args_2: string): void",
77+
overloadsCount: 2,
78+
parameterCount: 3,
79+
parameterName: "args_1",
80+
parameterSpan: "args_1: string",
81+
isVariadic: false,
82+
overrideSelectedItemIndex: 1
83+
},
84+
{
85+
marker: "8",
86+
text: "foo(args_0: number, args_1: string, args_2: string): void",
87+
overloadsCount: 2,
88+
parameterCount: 3,
89+
parameterName: "args_2",
90+
parameterSpan: "args_2: string",
91+
isVariadic: false,
92+
overrideSelectedItemIndex: 1
93+
},
94+
);

0 commit comments

Comments
 (0)