diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts
index 2e2bc61136a..43600422a5c 100644
--- a/src/services/jsDoc.ts
+++ b/src/services/jsDoc.ts
@@ -169,7 +169,27 @@ namespace ts.JsDoc {
case SyntaxKind.JSDocAugmentsTag:
return withNode((tag as JSDocAugmentsTag).class);
case SyntaxKind.JSDocTemplateTag:
- return addComment((tag as JSDocTemplateTag).typeParameters.map(tp => tp.getText()).join(", "));
+ const templateTag = tag as JSDocTemplateTag;
+ const displayParts: SymbolDisplayPart[] = [];
+ if (templateTag.constraint) {
+ displayParts.push(textPart(templateTag.constraint.getText()));
+ }
+ if (length(templateTag.typeParameters)) {
+ if (length(displayParts)) {
+ displayParts.push(spacePart());
+ }
+ const lastTypeParameter = templateTag.typeParameters[templateTag.typeParameters.length - 1];
+ forEach(templateTag.typeParameters, tp => {
+ displayParts.push(namePart(tp.getText()));
+ if (lastTypeParameter !== tp) {
+ displayParts.push(...[punctuationPart(SyntaxKind.CommaToken), spacePart()]);
+ }
+ });
+ }
+ if (comment) {
+ displayParts.push(...[spacePart(), ...getDisplayPartsFromComment(comment, checker)]);
+ }
+ return displayParts;
case SyntaxKind.JSDocTypeTag:
return withNode((tag as JSDocTypeTag).typeExpression);
case SyntaxKind.JSDocTypedefTag:
diff --git a/tests/baselines/reference/jsdocReturnsTag.baseline b/tests/baselines/reference/jsdocReturnsTag.baseline
index 1ab8b6a2439..9ee6f61706e 100644
--- a/tests/baselines/reference/jsdocReturnsTag.baseline
+++ b/tests/baselines/reference/jsdocReturnsTag.baseline
@@ -117,7 +117,7 @@
"text": [
{
"text": "T",
- "kind": "text"
+ "kind": "typeParameterName"
}
]
},
diff --git a/tests/baselines/reference/quickInfoJsDocTags10.baseline b/tests/baselines/reference/quickInfoJsDocTags10.baseline
new file mode 100644
index 00000000000..e4e616652aa
--- /dev/null
+++ b/tests/baselines/reference/quickInfoJsDocTags10.baseline
@@ -0,0 +1,177 @@
+[
+ {
+ "marker": {
+ "fileName": "/tests/cases/fourslash/quickInfoJsDocTags10.js",
+ "position": 80,
+ "name": ""
+ },
+ "quickInfo": {
+ "kind": "const",
+ "kindModifiers": "",
+ "textSpan": {
+ "start": 80,
+ "length": 3
+ },
+ "displayParts": [
+ {
+ "text": "const",
+ "kind": "keyword"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "foo",
+ "kind": "localName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "<",
+ "kind": "punctuation"
+ },
+ {
+ "text": "T1",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T2",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ">",
+ "kind": "punctuation"
+ },
+ {
+ "text": "(",
+ "kind": "punctuation"
+ },
+ {
+ "text": "a",
+ "kind": "parameterName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T1",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "b",
+ "kind": "parameterName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "any",
+ "kind": "keyword"
+ },
+ {
+ "text": ")",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "=>",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "void",
+ "kind": "keyword"
+ }
+ ],
+ "documentation": [],
+ "tags": [
+ {
+ "name": "param",
+ "text": [
+ {
+ "text": "a",
+ "kind": "text"
+ }
+ ]
+ },
+ {
+ "name": "param",
+ "text": [
+ {
+ "text": "a",
+ "kind": "text"
+ }
+ ]
+ },
+ {
+ "name": "template",
+ "text": [
+ {
+ "text": "T1",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T2",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "Comment Text",
+ "kind": "text"
+ }
+ ]
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/quickInfoJsDocTags11.baseline b/tests/baselines/reference/quickInfoJsDocTags11.baseline
new file mode 100644
index 00000000000..86d49f8089e
--- /dev/null
+++ b/tests/baselines/reference/quickInfoJsDocTags11.baseline
@@ -0,0 +1,230 @@
+[
+ {
+ "marker": {
+ "fileName": "/tests/cases/fourslash/quickInfoJsDocTags11.js",
+ "position": 120,
+ "name": ""
+ },
+ "quickInfo": {
+ "kind": "const",
+ "kindModifiers": "",
+ "textSpan": {
+ "start": 120,
+ "length": 3
+ },
+ "displayParts": [
+ {
+ "text": "const",
+ "kind": "keyword"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "foo",
+ "kind": "localName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "<",
+ "kind": "punctuation"
+ },
+ {
+ "text": "T1",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "extends",
+ "kind": "keyword"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "number",
+ "kind": "keyword"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T2",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "extends",
+ "kind": "keyword"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "number",
+ "kind": "keyword"
+ },
+ {
+ "text": ">",
+ "kind": "punctuation"
+ },
+ {
+ "text": "(",
+ "kind": "punctuation"
+ },
+ {
+ "text": "a",
+ "kind": "parameterName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T1",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "b",
+ "kind": "parameterName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T2",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ")",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "=>",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "void",
+ "kind": "keyword"
+ }
+ ],
+ "documentation": [],
+ "tags": [
+ {
+ "name": "param",
+ "text": [
+ {
+ "text": "a",
+ "kind": "text"
+ }
+ ]
+ },
+ {
+ "name": "param",
+ "text": [
+ {
+ "text": "b",
+ "kind": "text"
+ }
+ ]
+ },
+ {
+ "name": "template",
+ "text": [
+ {
+ "text": "{number}",
+ "kind": "text"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T1",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "Comment T1",
+ "kind": "text"
+ }
+ ]
+ },
+ {
+ "name": "template",
+ "text": [
+ {
+ "text": "{number}",
+ "kind": "text"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T2",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "Comment T2",
+ "kind": "text"
+ }
+ ]
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/quickInfoJsDocTags7.baseline b/tests/baselines/reference/quickInfoJsDocTags7.baseline
new file mode 100644
index 00000000000..4b5d48a2901
--- /dev/null
+++ b/tests/baselines/reference/quickInfoJsDocTags7.baseline
@@ -0,0 +1,100 @@
+[
+ {
+ "marker": {
+ "fileName": "/tests/cases/fourslash/quickInfoJsDocTags7.js",
+ "position": 116,
+ "name": ""
+ },
+ "quickInfo": {
+ "kind": "const",
+ "kindModifiers": "",
+ "textSpan": {
+ "start": 116,
+ "length": 3
+ },
+ "displayParts": [
+ {
+ "text": "const",
+ "kind": "keyword"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "foo",
+ "kind": "localName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "(",
+ "kind": "punctuation"
+ },
+ {
+ "text": "t",
+ "kind": "parameterName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ")",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "=>",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "number",
+ "kind": "keyword"
+ }
+ ],
+ "documentation": [],
+ "tags": [
+ {
+ "name": "type",
+ "text": [
+ {
+ "text": "{(t: T) => number}",
+ "kind": "text"
+ }
+ ]
+ },
+ {
+ "name": "template",
+ "text": [
+ {
+ "text": "T",
+ "kind": "typeParameterName"
+ }
+ ]
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/quickInfoJsDocTags8.baseline b/tests/baselines/reference/quickInfoJsDocTags8.baseline
new file mode 100644
index 00000000000..def6b90bcf8
--- /dev/null
+++ b/tests/baselines/reference/quickInfoJsDocTags8.baseline
@@ -0,0 +1,108 @@
+[
+ {
+ "marker": {
+ "fileName": "/tests/cases/fourslash/quickInfoJsDocTags8.js",
+ "position": 122,
+ "name": ""
+ },
+ "quickInfo": {
+ "kind": "const",
+ "kindModifiers": "",
+ "textSpan": {
+ "start": 122,
+ "length": 3
+ },
+ "displayParts": [
+ {
+ "text": "const",
+ "kind": "keyword"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "foo",
+ "kind": "localName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "(",
+ "kind": "punctuation"
+ },
+ {
+ "text": "t",
+ "kind": "parameterName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ")",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "=>",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "number",
+ "kind": "keyword"
+ }
+ ],
+ "documentation": [],
+ "tags": [
+ {
+ "name": "type",
+ "text": [
+ {
+ "text": "{(t: T) => number}",
+ "kind": "text"
+ }
+ ]
+ },
+ {
+ "name": "template",
+ "text": [
+ {
+ "text": "{Foo}",
+ "kind": "text"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T",
+ "kind": "typeParameterName"
+ }
+ ]
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/quickInfoJsDocTags9.baseline b/tests/baselines/reference/quickInfoJsDocTags9.baseline
new file mode 100644
index 00000000000..248a657146b
--- /dev/null
+++ b/tests/baselines/reference/quickInfoJsDocTags9.baseline
@@ -0,0 +1,116 @@
+[
+ {
+ "marker": {
+ "fileName": "/tests/cases/fourslash/quickInfoJsDocTags9.js",
+ "position": 135,
+ "name": ""
+ },
+ "quickInfo": {
+ "kind": "const",
+ "kindModifiers": "",
+ "textSpan": {
+ "start": 135,
+ "length": 3
+ },
+ "displayParts": [
+ {
+ "text": "const",
+ "kind": "keyword"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "foo",
+ "kind": "localName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "(",
+ "kind": "punctuation"
+ },
+ {
+ "text": "t",
+ "kind": "parameterName"
+ },
+ {
+ "text": ":",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ")",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "=>",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "number",
+ "kind": "keyword"
+ }
+ ],
+ "documentation": [],
+ "tags": [
+ {
+ "name": "type",
+ "text": [
+ {
+ "text": "{(t: T) => number}",
+ "kind": "text"
+ }
+ ]
+ },
+ {
+ "name": "template",
+ "text": [
+ {
+ "text": "{Foo}",
+ "kind": "text"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "T",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "Comment Text",
+ "kind": "text"
+ }
+ ]
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/signatureHelpTypeArguments2.baseline b/tests/baselines/reference/signatureHelpTypeArguments2.baseline
index 75971fa59ce..7e70e96ada6 100644
--- a/tests/baselines/reference/signatureHelpTypeArguments2.baseline
+++ b/tests/baselines/reference/signatureHelpTypeArguments2.baseline
@@ -213,7 +213,7 @@
"text": [
{
"text": "W",
- "kind": "text"
+ "kind": "typeParameterName"
}
]
},
@@ -221,7 +221,19 @@
"name": "template",
"text": [
{
- "text": "U, V",
+ "text": "U",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "V",
"kind": "typeParameterName"
},
{
@@ -494,7 +506,7 @@
"text": [
{
"text": "W",
- "kind": "text"
+ "kind": "typeParameterName"
}
]
},
@@ -502,7 +514,19 @@
"name": "template",
"text": [
{
- "text": "U, V",
+ "text": "U",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "V",
"kind": "typeParameterName"
},
{
@@ -775,7 +799,7 @@
"text": [
{
"text": "W",
- "kind": "text"
+ "kind": "typeParameterName"
}
]
},
@@ -783,7 +807,19 @@
"name": "template",
"text": [
{
- "text": "U, V",
+ "text": "U",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "V",
"kind": "typeParameterName"
},
{
@@ -1056,7 +1092,7 @@
"text": [
{
"text": "W",
- "kind": "text"
+ "kind": "typeParameterName"
}
]
},
@@ -1064,7 +1100,19 @@
"name": "template",
"text": [
{
- "text": "U, V",
+ "text": "U",
+ "kind": "typeParameterName"
+ },
+ {
+ "text": ",",
+ "kind": "punctuation"
+ },
+ {
+ "text": " ",
+ "kind": "space"
+ },
+ {
+ "text": "V",
"kind": "typeParameterName"
},
{
diff --git a/tests/cases/fourslash/quickInfoJsDocTags10.ts b/tests/cases/fourslash/quickInfoJsDocTags10.ts
new file mode 100644
index 00000000000..f635da3ee57
--- /dev/null
+++ b/tests/cases/fourslash/quickInfoJsDocTags10.ts
@@ -0,0 +1,14 @@
+///
+
+// @noEmit: true
+// @allowJs: true
+
+// @Filename: quickInfoJsDocTags10.js
+/////**
+//// * @param {T1} a
+//// * @param {T2} a
+//// * @template T1,T2 Comment Text
+//// */
+////const /**/foo = (a, b) => {};
+
+verify.baselineQuickInfo();
diff --git a/tests/cases/fourslash/quickInfoJsDocTags11.ts b/tests/cases/fourslash/quickInfoJsDocTags11.ts
new file mode 100644
index 00000000000..348940ba091
--- /dev/null
+++ b/tests/cases/fourslash/quickInfoJsDocTags11.ts
@@ -0,0 +1,15 @@
+///
+
+// @noEmit: true
+// @allowJs: true
+
+// @Filename: quickInfoJsDocTags11.js
+/////**
+//// * @param {T1} a
+//// * @param {T2} b
+//// * @template {number} T1 Comment T1
+//// * @template {number} T2 Comment T2
+//// */
+////const /**/foo = (a, b) => {};
+
+verify.baselineQuickInfo();
diff --git a/tests/cases/fourslash/quickInfoJsDocTags7.ts b/tests/cases/fourslash/quickInfoJsDocTags7.ts
new file mode 100644
index 00000000000..3cc00ad803b
--- /dev/null
+++ b/tests/cases/fourslash/quickInfoJsDocTags7.ts
@@ -0,0 +1,17 @@
+///
+
+// @noEmit: true
+// @allowJs: true
+
+// @Filename: quickInfoJsDocTags7.js
+/////**
+//// * @typedef {{ [x: string]: any, y: number }} Foo
+//// */
+////
+/////**
+//// * @type {(t: T) => number}
+//// * @template T
+//// */
+////const /**/foo = t => t.y;
+
+verify.baselineQuickInfo();
diff --git a/tests/cases/fourslash/quickInfoJsDocTags8.ts b/tests/cases/fourslash/quickInfoJsDocTags8.ts
new file mode 100644
index 00000000000..cc9c5aa1606
--- /dev/null
+++ b/tests/cases/fourslash/quickInfoJsDocTags8.ts
@@ -0,0 +1,17 @@
+///
+
+// @noEmit: true
+// @allowJs: true
+
+// @Filename: quickInfoJsDocTags8.js
+/////**
+//// * @typedef {{ [x: string]: any, y: number }} Foo
+//// */
+////
+/////**
+//// * @type {(t: T) => number}
+//// * @template {Foo} T
+//// */
+////const /**/foo = t => t.y;
+
+verify.baselineQuickInfo();
diff --git a/tests/cases/fourslash/quickInfoJsDocTags9.ts b/tests/cases/fourslash/quickInfoJsDocTags9.ts
new file mode 100644
index 00000000000..0558786a9ba
--- /dev/null
+++ b/tests/cases/fourslash/quickInfoJsDocTags9.ts
@@ -0,0 +1,17 @@
+///
+
+// @noEmit: true
+// @allowJs: true
+
+// @Filename: quickInfoJsDocTags9.js
+/////**
+//// * @typedef {{ [x: string]: any, y: number }} Foo
+//// */
+////
+/////**
+//// * @type {(t: T) => number}
+//// * @template {Foo} T Comment Text
+//// */
+////const /**/foo = t => t.y;
+
+verify.baselineQuickInfo();