mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Handle @typedef tag with missing type (#18662)
* Handle @typedef tag with missing type * Add single quotes to diagnostic * Remove redundant jsdoc checking (now done on every source element) * Update baselines
This commit is contained in:
parent
5a0c60a9a1
commit
b4018a2ef1
@ -5124,7 +5124,9 @@ namespace ts {
|
||||
|
||||
const declaration = <JSDocTypedefTag | TypeAliasDeclaration>find(symbol.declarations, d =>
|
||||
d.kind === SyntaxKind.JSDocTypedefTag || d.kind === SyntaxKind.TypeAliasDeclaration);
|
||||
let type = getTypeFromTypeNode(declaration.kind === SyntaxKind.JSDocTypedefTag ? declaration.typeExpression : declaration.type);
|
||||
const typeNode = declaration.kind === SyntaxKind.JSDocTypedefTag ? declaration.typeExpression : declaration.type;
|
||||
// If typeNode is missing, we will error in checkJSDocTypedefTag.
|
||||
let type = typeNode ? getTypeFromTypeNode(typeNode) : unknownType;
|
||||
|
||||
if (popTypeResolution()) {
|
||||
const typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
|
||||
@ -19779,11 +19781,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function checkJSDoc(node: FunctionDeclaration | MethodDeclaration) {
|
||||
if (!isInJavaScriptFile(node)) {
|
||||
return;
|
||||
function checkJSDocTypedefTag(node: JSDocTypedefTag) {
|
||||
if (!node.typeExpression) {
|
||||
// If the node had `@property` tags, `typeExpression` would have been set to the first property tag.
|
||||
error(node.name, Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags);
|
||||
}
|
||||
forEach(node.jsDoc, checkSourceElement);
|
||||
}
|
||||
|
||||
function checkJSDocComment(node: JSDoc) {
|
||||
@ -19795,7 +19797,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkFunctionOrMethodDeclaration(node: FunctionDeclaration | MethodDeclaration): void {
|
||||
checkJSDoc(node);
|
||||
checkDecorators(node);
|
||||
checkSignatureDeclaration(node);
|
||||
const functionFlags = getFunctionFlags(node);
|
||||
@ -22429,6 +22430,12 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInJavaScriptFile(node) && (node as JSDocContainer).jsDoc) {
|
||||
for (const jsdoc of (node as JSDocContainer).jsDoc) {
|
||||
checkJSDocComment(jsdoc);
|
||||
}
|
||||
}
|
||||
|
||||
const kind = node.kind;
|
||||
if (cancellationToken) {
|
||||
// Only bother checking on a few construct kinds. We don't want to be excessively
|
||||
@ -22483,6 +22490,8 @@ namespace ts {
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
case SyntaxKind.TypeOperator:
|
||||
return checkSourceElement((<ParenthesizedTypeNode | TypeOperatorNode>node).type);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return checkJSDocTypedefTag(node as JSDocTypedefTag);
|
||||
case SyntaxKind.JSDocComment:
|
||||
return checkJSDocComment(node as JSDoc);
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
|
||||
@ -3507,6 +3507,10 @@
|
||||
"category": "Error",
|
||||
"code": 8020
|
||||
},
|
||||
"JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.": {
|
||||
"category": "Error",
|
||||
"code": 8021
|
||||
},
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
|
||||
"category": "Error",
|
||||
"code": 9002
|
||||
|
||||
23
tests/baselines/reference/jsdocTypedefMissingType.errors.txt
Normal file
23
tests/baselines/reference/jsdocTypedefMissingType.errors.txt
Normal file
@ -0,0 +1,23 @@
|
||||
/a.js(2,14): error TS8021: JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.
|
||||
/a.js(12,11): error TS1005: '{' expected.
|
||||
|
||||
|
||||
==== /a.js (2 errors) ====
|
||||
// Bad: missing a type
|
||||
/** @typedef T */
|
||||
~
|
||||
!!! error TS8021: JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.
|
||||
|
||||
const t = 0;
|
||||
|
||||
// OK: missing a type, but have property tags.
|
||||
/**
|
||||
* @typedef Person
|
||||
* @property {string} name
|
||||
*/
|
||||
|
||||
/** @type Person */
|
||||
~~~~~~
|
||||
!!! error TS1005: '{' expected.
|
||||
const person = { name: "" };
|
||||
|
||||
18
tests/baselines/reference/jsdocTypedefMissingType.symbols
Normal file
18
tests/baselines/reference/jsdocTypedefMissingType.symbols
Normal file
@ -0,0 +1,18 @@
|
||||
=== /a.js ===
|
||||
// Bad: missing a type
|
||||
/** @typedef T */
|
||||
|
||||
const t = 0;
|
||||
>t : Symbol(t, Decl(a.js, 3, 5))
|
||||
|
||||
// OK: missing a type, but have property tags.
|
||||
/**
|
||||
* @typedef Person
|
||||
* @property {string} name
|
||||
*/
|
||||
|
||||
/** @type Person */
|
||||
const person = { name: "" };
|
||||
>person : Symbol(person, Decl(a.js, 12, 5))
|
||||
>name : Symbol(name, Decl(a.js, 12, 16))
|
||||
|
||||
21
tests/baselines/reference/jsdocTypedefMissingType.types
Normal file
21
tests/baselines/reference/jsdocTypedefMissingType.types
Normal file
@ -0,0 +1,21 @@
|
||||
=== /a.js ===
|
||||
// Bad: missing a type
|
||||
/** @typedef T */
|
||||
|
||||
const t = 0;
|
||||
>t : 0
|
||||
>0 : 0
|
||||
|
||||
// OK: missing a type, but have property tags.
|
||||
/**
|
||||
* @typedef Person
|
||||
* @property {string} name
|
||||
*/
|
||||
|
||||
/** @type Person */
|
||||
const person = { name: "" };
|
||||
>person : { [x: string]: any; name: string; }
|
||||
>{ name: "" } : { [x: string]: any; name: string; }
|
||||
>name : string
|
||||
>"" : ""
|
||||
|
||||
18
tests/cases/compiler/jsdocTypedefMissingType.ts
Normal file
18
tests/cases/compiler/jsdocTypedefMissingType.ts
Normal file
@ -0,0 +1,18 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
|
||||
// @Filename: /a.js
|
||||
// Bad: missing a type
|
||||
/** @typedef T */
|
||||
|
||||
const t = 0;
|
||||
|
||||
// OK: missing a type, but have property tags.
|
||||
/**
|
||||
* @typedef Person
|
||||
* @property {string} name
|
||||
*/
|
||||
|
||||
/** @type Person */
|
||||
const person = { name: "" };
|
||||
11
tests/cases/fourslash/quickInfoJsdocTypedefMissingType.ts
Normal file
11
tests/cases/fourslash/quickInfoJsdocTypedefMissingType.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowJs: true
|
||||
|
||||
// @Filename: /a.js
|
||||
/////**
|
||||
//// * @typedef /**/A
|
||||
//// */
|
||||
////var x;
|
||||
|
||||
verify.quickInfoAt("", "type A = any");
|
||||
Loading…
x
Reference in New Issue
Block a user