Skip to content

Commit 937afab

Browse files
author
Andy
authored
Support signature help for contextual parameter type (#26022)
1 parent eeb19c1 commit 937afab

7 files changed

+241
-82
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ namespace ts {
188188
const node = getParseTreeNode(nodeIn, isExpression);
189189
return node ? getContextualType(node) : undefined;
190190
},
191+
getContextualTypeForObjectLiteralElement: nodeIn => {
192+
const node = getParseTreeNode(nodeIn, isObjectLiteralElementLike);
193+
return node ? getContextualTypeForObjectLiteralElement(node) : undefined;
194+
},
191195
getContextualTypeForArgumentAtIndex: (nodeIn, argIndex) => {
192196
const node = getParseTreeNode(nodeIn, isCallLikeExpression);
193197
return node && getContextualTypeForArgumentAtIndex(node, argIndex);
@@ -16219,7 +16223,7 @@ namespace ts {
1621916223
return getContextualTypeForBinaryOperand(node);
1622016224
case SyntaxKind.PropertyAssignment:
1622116225
case SyntaxKind.ShorthandPropertyAssignment:
16222-
return getContextualTypeForObjectLiteralElement(<ObjectLiteralElementLike>parent);
16226+
return getContextualTypeForObjectLiteralElement(<PropertyAssignment | ShorthandPropertyAssignment>parent);
1622316227
case SyntaxKind.SpreadAssignment:
1622416228
return getApparentTypeOfContextualType(parent.parent as ObjectLiteralExpression);
1622516229
case SyntaxKind.ArrayLiteralExpression: {

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2973,6 +2973,7 @@ namespace ts {
29732973
getAugmentedPropertiesOfType(type: Type): Symbol[];
29742974
getRootSymbols(symbol: Symbol): Symbol[];
29752975
getContextualType(node: Expression): Type | undefined;
2976+
/* @internal */ getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike): Type | undefined;
29762977
/* @internal */ getContextualTypeForArgumentAtIndex(call: CallLikeExpression, argIndex: number): Type | undefined;
29772978
/* @internal */ getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute): Type | undefined;
29782979
/* @internal */ isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike): boolean;

src/services/signatureHelp.ts

Lines changed: 145 additions & 77 deletions
Large diffs are not rendered by default.

tests/cases/fourslash/completionsRecommended_contextualTypes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
// @Filename: /a.tsx
66
////enum E {}
77
////enum F {}
8+
////interface I { e: E }
89
////function f(e: E, f: F) {}
910
////f(/*arg0*/, /*arg1*/);
1011
////
12+
////const i: I = { e: /*prop*/ };
13+
////
1114
////function tag(arr: TemplateStringsArray, x: E) {}
1215
////tag`${/*tag*/}`;
1316
////
@@ -17,6 +20,7 @@
1720

1821
recommended("arg0");
1922
recommended("arg1", { enumName: "F" });
23+
recommended("prop");
2024
recommended("tag");
2125
recommended("jsx");
2226
recommended("jsx2", { insertText: "{E}" });

tests/cases/fourslash/genericFunctionSignatureHelp3.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ verify.signatureHelp(
2020
{ marker: "1", text: "foo1(x: number, callback: (y1: {}) => number): void" },
2121
// TODO: GH#23631
2222
// { marker: "2", text: "foo2(x: number, callback: (y2: {}) => number): void" },
23-
{ marker: "3", text: "foo3(x: number, callback: (y3: {}) => number): void" },
23+
{ marker: "3", text: "callback(y3: {}): number" },
2424
// TODO: GH#23631
2525
// { marker: "4", text: "foo4(x: number, callback: (y4: string) => number): void" },
26-
{ marker: "5", text: "foo5(x: number, callback: (y5: string) => number): void" },
26+
{ marker: "5", text: "callback(y5: string): number" },
2727
);
2828

2929
goTo.marker('6');

tests/cases/fourslash/genericFunctionSignatureHelp3MultiFile.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
verify.signatureHelp(
2727
{ marker: "1", text: "foo1(x: number, callback: (y1: {}) => number): void" },
2828
{ marker: "2", text: "foo2(x: number, callback: (y2: {}) => number): void" },
29-
{ marker: "3", text: "foo3(x: number, callback: (y3: {}) => number): void" },
29+
{ marker: "3", text: "callback(y3: {}): number" },
3030
{ marker: "4", text: "foo4(x: number, callback: (y4: string) => number): void" },
31-
{ marker: "5", text: "foo5(x: number, callback: (y5: string) => number): void" },
31+
{ marker: "5", text: "callback(y5: string): number" },
3232
);
3333

3434
goTo.marker('6');
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////interface I {
4+
//// m(n: number, s: string): void;
5+
//// m2: () => void;
6+
////}
7+
////declare function takesObj(i: I): void;
8+
////takesObj({ m: (/*takesObj0*/) });
9+
////takesObj({ m(/*takesObj1*/) });
10+
////takesObj({ m: function(/*takesObj2*/) });
11+
////takesObj({ m2: (/*takesObj3*/) });
12+
////
13+
////declare function takesCb(cb: (n: number, s: string, b: boolean) => void): void;
14+
////takesCb((/*contextualParameter1*/));
15+
////takesCb((/*contextualParameter1b*/) => {});
16+
////takesCb((n, /*contextualParameter2*/));
17+
////takesCb((n, s, /*contextualParameter3*/));
18+
////takesCb((n,/*contextualParameter3_2*/ s, b));
19+
////takesCb((n, s, b, /*contextualParameter4*/));
20+
////
21+
////type Cb = () => void;
22+
////const cb: Cb = (/*contextualTypeAlias*/)
23+
////
24+
////const cb2: () => void = (/*contextualFunctionType*/)
25+
26+
verify.signatureHelp(
27+
{
28+
marker: ["takesObj0", "takesObj1", "takesObj2"],
29+
text: "m(n: number, s: string): void",
30+
parameterCount: 2,
31+
parameterName: "n",
32+
parameterSpan: "n: number",
33+
},
34+
{
35+
marker: "takesObj3",
36+
text: "m2(): void",
37+
parameterCount: 0,
38+
},
39+
{
40+
marker: ["contextualParameter1", "contextualParameter1b"],
41+
text: "cb(n: number, s: string, b: boolean): void",
42+
parameterCount: 3,
43+
parameterName: "n",
44+
parameterSpan: "n: number",
45+
},
46+
{
47+
marker: "contextualParameter2",
48+
text: "cb(n: number, s: string, b: boolean): void",
49+
parameterCount: 3,
50+
parameterName: "s",
51+
parameterSpan: "s: string",
52+
},
53+
{
54+
marker: "contextualParameter3",
55+
text: "cb(n: number, s: string, b: boolean): void",
56+
parameterCount: 3,
57+
parameterName: "b",
58+
parameterSpan: "b: boolean",
59+
},
60+
{
61+
marker: "contextualParameter3_2",
62+
text: "cb(n: number, s: string, b: boolean): void",
63+
parameterCount: 3,
64+
parameterName: "s",
65+
parameterSpan: "s: string",
66+
},
67+
{
68+
marker: "contextualParameter4",
69+
text: "cb(n: number, s: string, b: boolean): void",
70+
parameterCount: 3,
71+
},
72+
{
73+
marker: "contextualTypeAlias",
74+
text: "Cb(): void",
75+
parameterCount: 0,
76+
},
77+
{
78+
marker: "contextualFunctionType",
79+
text: "cb2(): void",
80+
parameterCount: 0,
81+
},
82+
);

0 commit comments

Comments
 (0)