Skip to content

Commit 3718182

Browse files
authored
Don't block completion after end of type parameters in JSX elements (microsoft#47501)
1 parent 0f3809e commit 3718182

File tree

2 files changed

+68
-9
lines changed

2 files changed

+68
-9
lines changed

src/services/completions.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2543,16 +2543,20 @@ namespace ts.Completions {
25432543
}
25442544

25452545
if (contextToken.kind === SyntaxKind.GreaterThanToken && contextToken.parent) {
2546+
// <Component<string> /**/ />
2547+
// <Component<string> /**/ ><Component>
2548+
// - contextToken: GreaterThanToken (before cursor)
2549+
// - location: JsxSelfClosingElement or JsxOpeningElement
2550+
// - contextToken.parent === location
2551+
if (location === contextToken.parent && (location.kind === SyntaxKind.JsxOpeningElement || location.kind === SyntaxKind.JsxSelfClosingElement)) {
2552+
return false;
2553+
}
2554+
25462555
if (contextToken.parent.kind === SyntaxKind.JsxOpeningElement) {
2547-
// Two possibilities:
2548-
// 1. <div>/**/
2549-
// - contextToken: GreaterThanToken (before cursor)
2550-
// - location: JSXElement
2551-
// - different parents (JSXOpeningElement, JSXElement)
2552-
// 2. <Component<string> /**/>
2553-
// - contextToken: GreaterThanToken (before cursor)
2554-
// - location: GreaterThanToken (after cursor)
2555-
// - same parent (JSXOpeningElement)
2556+
// <div>/**/
2557+
// - contextToken: GreaterThanToken (before cursor)
2558+
// - location: JSXElement
2559+
// - different parents (JSXOpeningElement, JSXElement)
25562560
return location.parent.kind !== SyntaxKind.JsxOpeningElement;
25572561
}
25582562

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/// <reference path="fourslash.ts" />
2+
//@Filename: file.tsx
3+
4+
////declare const React: any;
5+
////
6+
////namespace JSX {
7+
//// export interface IntrinsicElements {
8+
//// div: any;
9+
//// }
10+
////}
11+
////
12+
////function GenericElement<T>(props: {xyz?: T}) {
13+
//// return <></>
14+
////}
15+
////
16+
////function fn1() {
17+
//// return <div>
18+
//// <GenericElement<number> /*1*/ />
19+
//// </div>
20+
////}
21+
////
22+
////function fn2() {
23+
//// return <>
24+
//// <GenericElement<number> /*2*/ />
25+
//// </>
26+
////}
27+
////function fn3() {
28+
//// return <div>
29+
//// <GenericElement<number> /*3*/ ></GenericElement>
30+
//// </div>
31+
////}
32+
////
33+
////function fn4() {
34+
//// return <>
35+
//// <GenericElement<number> /*4*/ ></GenericElement>
36+
//// </>
37+
////}
38+
39+
verify.completions(
40+
{
41+
marker: test.markers(),
42+
includes: {
43+
name: "xyz",
44+
insertText: "xyz={$1}",
45+
text: "(property) xyz?: number",
46+
isSnippet: true,
47+
sortText: completion.SortText.OptionalMember
48+
},
49+
preferences: {
50+
jsxAttributeCompletionStyle: "braces",
51+
includeCompletionsWithSnippetText: true,
52+
includeCompletionsWithInsertText: true,
53+
},
54+
},
55+
)

0 commit comments

Comments
 (0)