diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 19d04b0ac5..63f1696832 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -438,8 +438,10 @@ namespace ts { visitNode(cbNode, (node).typeExpression); } case SyntaxKind.JSDocTypeLiteral: - for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) { - visitNode(cbNode, tag); + if ((node as JSDocTypeLiteral).jsDocPropertyTags) { + for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) { + visitNode(cbNode, tag); + } } return; case SyntaxKind.PartiallyEmittedExpression: @@ -6652,19 +6654,18 @@ namespace ts { if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { let child: JSDocTypeTag | JSDocPropertyTag | false; let jsdocTypeLiteral: JSDocTypeLiteral; - let alreadyHasTypeTag = false; + let childTypeTag: JSDocTypeTag; const start = scanner.getStartPos(); while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Property))) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); } if (child.kind === SyntaxKind.JSDocTypeTag) { - if (alreadyHasTypeTag) { + if (childTypeTag) { break; } else { - jsdocTypeLiteral.jsDocTypeTag = child; - alreadyHasTypeTag = true; + childTypeTag = child; } } else { @@ -6678,7 +6679,9 @@ namespace ts { if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) { jsdocTypeLiteral.isArrayType = true; } - typedefTag.typeExpression = finishNode(jsdocTypeLiteral); + typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c9ba56506a..cfb08a7b05 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2211,7 +2211,6 @@ namespace ts { export interface JSDocTypeLiteral extends JSDocType { kind: SyntaxKind.JSDocTypeLiteral; jsDocPropertyTags?: ReadonlyArray; - jsDocTypeTag?: JSDocTypeTag; /** If true, then this type literal represents an *array* of its type. */ isArrayType?: boolean; } diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json index f0e42ae632..08d270286b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json @@ -34,38 +34,6 @@ "kind": "JSDocTypeLiteral", "pos": 26, "end": 98, - "jsDocTypeTag": { - "kind": "JSDocTypeTag", - "pos": 28, - "end": 42, - "atToken": { - "kind": "AtToken", - "pos": 28, - "end": 29 - }, - "tagName": { - "kind": "Identifier", - "pos": 29, - "end": 33, - "escapedText": "type" - }, - "typeExpression": { - "kind": "JSDocTypeExpression", - "pos": 34, - "end": 42, - "type": { - "kind": "TypeReference", - "pos": 35, - "end": 41, - "typeName": { - "kind": "Identifier", - "pos": 35, - "end": 41, - "escapedText": "Object" - } - } - } - }, "jsDocPropertyTags": [ { "kind": "JSDocPropertyTag", diff --git a/tests/baselines/reference/jsdocTwoLineTypedef.js b/tests/baselines/reference/jsdocTwoLineTypedef.js new file mode 100644 index 0000000000..b48d6a89a2 --- /dev/null +++ b/tests/baselines/reference/jsdocTwoLineTypedef.js @@ -0,0 +1,10 @@ +//// [jsdocTwoLineTypedef.ts] +// Regression from #18301 +/** + * @typedef LoadCallback + * @type {function} + */ +type LoadCallback = void; + + +//// [jsdocTwoLineTypedef.js] diff --git a/tests/baselines/reference/jsdocTwoLineTypedef.symbols b/tests/baselines/reference/jsdocTwoLineTypedef.symbols new file mode 100644 index 0000000000..80a69e5f52 --- /dev/null +++ b/tests/baselines/reference/jsdocTwoLineTypedef.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts === +// Regression from #18301 +/** + * @typedef LoadCallback + * @type {function} + */ +type LoadCallback = void; +>LoadCallback : Symbol(LoadCallback, Decl(jsdocTwoLineTypedef.ts, 0, 0)) + diff --git a/tests/baselines/reference/jsdocTwoLineTypedef.types b/tests/baselines/reference/jsdocTwoLineTypedef.types new file mode 100644 index 0000000000..5e0d05b3fe --- /dev/null +++ b/tests/baselines/reference/jsdocTwoLineTypedef.types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts === +// Regression from #18301 +/** + * @typedef LoadCallback + * @type {function} + */ +type LoadCallback = void; +>LoadCallback : void + diff --git a/tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts b/tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts new file mode 100644 index 0000000000..2a7ad0d7db --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts @@ -0,0 +1,6 @@ +// Regression from #18301 +/** + * @typedef LoadCallback + * @type {function} + */ +type LoadCallback = void;