Skip to content

Commit 952526c

Browse files
authored
Show interactive inlay hints in parameter types (#55918)
1 parent 38d09d4 commit 952526c

4 files changed

+247
-50
lines changed

src/services/inlayHints.ts

+12-13
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,14 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
253253
return;
254254
}
255255

256-
const hints = typeToInlayHintParts(declarationType);
257-
if (hints) {
258-
const hintText = typeof hints === "string" ? hints : hints.map(part => part.text).join("");
256+
const hintParts = typeToInlayHintParts(declarationType);
257+
if (hintParts) {
258+
const hintText = typeof hintParts === "string" ? hintParts : hintParts.map(part => part.text).join("");
259259
const isVariableNameMatchesType = preferences.includeInlayVariableTypeHintsWhenTypeMatchesName === false && equateStringsCaseInsensitive(decl.name.getText(), hintText);
260260
if (isVariableNameMatchesType) {
261261
return;
262262
}
263-
addTypeHints(hints, decl.name.end);
263+
addTypeHints(hintParts, decl.name.end);
264264
}
265265
}
266266

@@ -385,9 +385,9 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
385385
return;
386386
}
387387

388-
const hint = typeToInlayHintParts(returnType);
389-
if (hint) {
390-
addTypeHints(hint, getTypeAnnotationPosition(decl));
388+
const hintParts = typeToInlayHintParts(returnType);
389+
if (hintParts) {
390+
addTypeHints(hintParts, getTypeAnnotationPosition(decl));
391391
}
392392
}
393393

@@ -416,16 +416,16 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
416416
continue;
417417
}
418418

419-
const typeDisplayString = getParameterDeclarationTypeDisplayString(signature.parameters[i]);
420-
if (!typeDisplayString) {
419+
const typeHints = getParameterDeclarationTypeHints(signature.parameters[i]);
420+
if (!typeHints) {
421421
continue;
422422
}
423423

424-
addTypeHints(typeDisplayString, param.questionToken ? param.questionToken.end : param.name.end);
424+
addTypeHints(typeHints, param.questionToken ? param.questionToken.end : param.name.end);
425425
}
426426
}
427427

428-
function getParameterDeclarationTypeDisplayString(symbol: Symbol) {
428+
function getParameterDeclarationTypeHints(symbol: Symbol) {
429429
const valueDeclaration = symbol.valueDeclaration;
430430
if (!valueDeclaration || !isParameter(valueDeclaration)) {
431431
return undefined;
@@ -435,8 +435,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
435435
if (isModuleReferenceType(signatureParamType)) {
436436
return undefined;
437437
}
438-
439-
return printTypeInSingleLine(signatureParamType);
438+
return typeToInlayHintParts(signatureParamType);
440439
}
441440

442441
function printTypeInSingleLine(type: Type) {
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,258 @@
1-
const f1: F1 = (a, b) => { }
2-
^
1+
const f1: F1 = (a, b) => { }
2+
^
33
{
4-
"text": ": string",
5-
"position": 58,
4+
"text": "",
5+
"displayParts": [
6+
{
7+
"text": ": "
8+
},
9+
{
10+
"text": "string"
11+
}
12+
],
13+
"position": 60,
614
"kind": "Type",
715
"whitespaceBefore": true
816
}
917

10-
const f1: F1 = (a, b) => { }
11-
^
18+
const f1: F1 = (a, b) => { }
19+
^
1220
{
13-
"text": ": number",
14-
"position": 61,
21+
"text": "",
22+
"displayParts": [
23+
{
24+
"text": ": "
25+
},
26+
{
27+
"text": "number"
28+
}
29+
],
30+
"position": 63,
1531
"kind": "Type",
1632
"whitespaceBefore": true
1733
}
1834

19-
const f2: F1 = (a, b: number) => { }
20-
^
35+
const f2: F1 = (a, b: number) => { }
36+
^
2137
{
22-
"text": ": string",
23-
"position": 87,
38+
"text": "",
39+
"displayParts": [
40+
{
41+
"text": ": "
42+
},
43+
{
44+
"text": "string"
45+
}
46+
],
47+
"position": 90,
2448
"kind": "Type",
2549
"whitespaceBefore": true
2650
}
2751

28-
foo1((a) => { })
29-
^
52+
foo1((a) => { })
53+
^
3054
{
31-
"text": ": string",
32-
"position": 157,
55+
"text": "",
56+
"displayParts": [
57+
{
58+
"text": ": "
59+
},
60+
{
61+
"text": "string"
62+
}
63+
],
64+
"position": 162,
3365
"kind": "Type",
3466
"whitespaceBefore": true
3567
}
3668

37-
foo2((a) => { })
69+
foo2((a) => { })
70+
^
71+
{
72+
"text": "",
73+
"displayParts": [
74+
{
75+
"text": ": "
76+
},
77+
{
78+
"text": "2"
79+
},
80+
{
81+
"text": " | "
82+
},
83+
{
84+
"text": "3"
85+
}
86+
],
87+
"position": 239,
88+
"kind": "Type",
89+
"whitespaceBefore": true
90+
}
91+
92+
foo3(a => {
3893
^
3994
{
40-
"text": ": 2 | 3",
41-
"position": 232,
95+
"text": "",
96+
"displayParts": [
97+
{
98+
"text": ": "
99+
},
100+
{
101+
"text": "("
102+
},
103+
{
104+
"text": "c"
105+
},
106+
{
107+
"text": ": "
108+
},
109+
{
110+
"text": "("
111+
},
112+
{
113+
"text": "d"
114+
},
115+
{
116+
"text": ": "
117+
},
118+
{
119+
"text": "2"
120+
},
121+
{
122+
"text": " | "
123+
},
124+
{
125+
"text": "3"
126+
},
127+
{
128+
"text": ")"
129+
},
130+
{
131+
"text": " => "
132+
},
133+
{
134+
"text": "void"
135+
},
136+
{
137+
"text": ")"
138+
},
139+
{
140+
"text": " => "
141+
},
142+
{
143+
"text": "void"
144+
}
145+
],
146+
"position": 340,
42147
"kind": "Type",
43148
"whitespaceBefore": true
44149
}
45150

46-
foo3(a => {
47-
^
151+
a(d => {})
152+
^
48153
{
49-
"text": ": (c: (d: 2 | 3) => void) => void",
50-
"position": 331,
154+
"text": "",
155+
"displayParts": [
156+
{
157+
"text": ": "
158+
},
159+
{
160+
"text": "2"
161+
},
162+
{
163+
"text": " | "
164+
},
165+
{
166+
"text": "3"
167+
}
168+
],
169+
"position": 354,
51170
"kind": "Type",
52171
"whitespaceBefore": true
53172
}
54173

55-
a(d => {})
56-
^
174+
foo4(1, a => { })
175+
^
57176
{
58-
"text": ": 2 | 3",
59-
"position": 344,
177+
"text": "",
178+
"displayParts": [
179+
{
180+
"text": ": "
181+
},
182+
{
183+
"text": "number"
184+
}
185+
],
186+
"position": 422,
60187
"kind": "Type",
61188
"whitespaceBefore": true
62189
}
63190

64-
foo4(1, a => { })
65-
^
191+
const foo5: F2 = (a) => { }
192+
^
66193
{
67-
"text": ": number",
68-
"position": 409,
194+
"text": "",
195+
"displayParts": [
196+
{
197+
"text": ": "
198+
},
199+
{
200+
"text": "{"
201+
},
202+
{
203+
"text": " "
204+
},
205+
{
206+
"text": "a"
207+
},
208+
{
209+
"text": ": "
210+
},
211+
{
212+
"text": "number"
213+
},
214+
{
215+
"text": "; "
216+
},
217+
{
218+
"text": "b"
219+
},
220+
{
221+
"text": ": "
222+
},
223+
{
224+
"text": "string"
225+
},
226+
{
227+
"text": " "
228+
},
229+
{
230+
"text": "}"
231+
}
232+
],
233+
"position": 510,
69234
"kind": "Type",
70235
"whitespaceBefore": true
71236
}
72237

73-
const foo5: F2 = (a) => { }
74-
^
238+
foo4(p => {})
239+
^
75240
{
76-
"text": ": { a: number; b: string; }",
77-
"position": 492,
241+
"text": "",
242+
"displayParts": [
243+
{
244+
"text": ": "
245+
},
246+
{
247+
"text": "Thing",
248+
"span": {
249+
"start": 529,
250+
"length": 5
251+
},
252+
"file": "/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes1.ts"
253+
}
254+
],
255+
"position": 595,
78256
"kind": "Type",
79257
"whitespaceBefore": true
80258
}

tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes3.baseline

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
bar: function (x?): void {
22
^
33
{
4-
"text": ": boolean",
4+
"text": "",
5+
"displayParts": [
6+
{
7+
"text": ": "
8+
},
9+
{
10+
"text": "boolean"
11+
}
12+
],
513
"position": 87,
614
"kind": "Type",
715
"whitespaceBefore": true
@@ -10,7 +18,15 @@
1018
set foo(value) { this.#value = value; }
1119
^
1220
{
13-
"text": ": number",
21+
"text": "",
22+
"displayParts": [
23+
{
24+
"text": ": "
25+
},
26+
{
27+
"text": "number"
28+
}
29+
],
1430
"position": 250,
1531
"kind": "Type",
1632
"whitespaceBefore": true

0 commit comments

Comments
 (0)