mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
No error on unmatchable @param tags (#22510)
* No errr on unmatchable `@param` tags Such as when the initializer is not a function, or when the function mentions `arguments` in its body. * Do not require dummy param for JS uses of arguments 1. JS functions that use `arguments` do not require a dummy parameter in order to get a type for the synthetic `args` parameter if there is an `@param` with a `...` type. 2.JS functions that use `arguments` and have an `@param` must have a type that is a `...` type. * Check for array type instead of syntactic `...` * Address PR comments * Update baselines
This commit is contained in:
+36
-17
@@ -6771,17 +6771,20 @@ namespace ts {
|
||||
return links.resolvedSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* A JS function gets a synthetic rest parameter if it references `arguments` AND:
|
||||
* 1. It has no parameters but at least one `@param` with a type that starts with `...`
|
||||
* OR
|
||||
* 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...`
|
||||
*/
|
||||
function maybeAddJsSyntheticRestParameter(declaration: SignatureDeclaration, parameters: Symbol[]): boolean {
|
||||
// JS functions get a free rest parameter if:
|
||||
// a) The last parameter has `...` preceding its type
|
||||
// b) It references `arguments` somewhere
|
||||
const lastParam = lastOrUndefined(declaration.parameters);
|
||||
const lastParamTags = lastParam && getJSDocParameterTags(lastParam);
|
||||
const lastParamVariadicType = firstDefined(lastParamTags, p =>
|
||||
p.typeExpression && isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined);
|
||||
if (!lastParamVariadicType && !containsArgumentsReference(declaration)) {
|
||||
if (!containsArgumentsReference(declaration)) {
|
||||
return false;
|
||||
}
|
||||
const lastParam = lastOrUndefined(declaration.parameters);
|
||||
const lastParamTags = lastParam ? getJSDocParameterTags(lastParam) : getJSDocTags(declaration).filter(isJSDocParameterTag);
|
||||
const lastParamVariadicType = firstDefined(lastParamTags, p =>
|
||||
p.typeExpression && isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined);
|
||||
|
||||
const syntheticArgsSymbol = createSymbol(SymbolFlags.Variable, "args" as __String);
|
||||
syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType;
|
||||
@@ -21459,9 +21462,24 @@ namespace ts {
|
||||
function checkJSDocParameterTag(node: JSDocParameterTag) {
|
||||
checkSourceElement(node.typeExpression);
|
||||
if (!getParameterSymbolFromJSDoc(node)) {
|
||||
error(node.name,
|
||||
Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name,
|
||||
idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name));
|
||||
const decl = getHostSignatureFromJSDoc(node);
|
||||
// don't issue an error for invalid hosts -- just functions --
|
||||
// and give a better error message when the host function mentions `arguments`
|
||||
// but the tag doesn't have an array type
|
||||
if (decl) {
|
||||
if (!containsArgumentsReference(decl)) {
|
||||
error(node.name,
|
||||
Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name,
|
||||
idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name));
|
||||
}
|
||||
else if (findLast(getJSDocTags(decl), isJSDocParameterTag) === node &&
|
||||
node.typeExpression && node.typeExpression.type &&
|
||||
!isArrayType(getTypeFromTypeNode(node.typeExpression.type))) {
|
||||
error(node.name,
|
||||
Diagnostics.The_last_param_tag_of_a_function_that_uses_arguments_must_have_an_array_type,
|
||||
idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24488,18 +24506,19 @@ namespace ts {
|
||||
const paramTag = parent.parent;
|
||||
if (isJSDocTypeExpression(parent) && isJSDocParameterTag(paramTag)) {
|
||||
// Else we will add a diagnostic, see `checkJSDocVariadicType`.
|
||||
const param = getParameterSymbolFromJSDoc(paramTag);
|
||||
if (param) {
|
||||
const host = getHostSignatureFromJSDoc(paramTag);
|
||||
const host = getHostSignatureFromJSDoc(paramTag);
|
||||
if (host) {
|
||||
/*
|
||||
Only return an array type if the corresponding parameter is marked as a rest parameter.
|
||||
Only return an array type if the corresponding parameter is marked as a rest parameter, or if there are no parameters.
|
||||
So in the following situation we will not create an array type:
|
||||
/** @param {...number} a * /
|
||||
function f(a) {}
|
||||
Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type.
|
||||
*/
|
||||
const lastParamDeclaration = host && last(host.parameters);
|
||||
if (lastParamDeclaration.symbol === param && isRestParameter(lastParamDeclaration)) {
|
||||
const lastParamDeclaration = lastOrUndefined(host.parameters);
|
||||
const symbol = getParameterSymbolFromJSDoc(paramTag);
|
||||
if (!lastParamDeclaration ||
|
||||
symbol && lastParamDeclaration.symbol === symbol && isRestParameter(lastParamDeclaration)) {
|
||||
return createArrayType(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3720,6 +3720,10 @@
|
||||
"category": "Error",
|
||||
"code": 8028
|
||||
},
|
||||
"The last @param tag of a function that uses 'arguments' must have an array type.": {
|
||||
"category": "Error",
|
||||
"code": 8029
|
||||
},
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
|
||||
"category": "Error",
|
||||
"code": 9002
|
||||
|
||||
Reference in New Issue
Block a user