Skip to content

Commit

Permalink
Improve behaviour of ... inside JSDoc functions (#22809)
Browse files Browse the repository at this point in the history
* No error for ... on last param of jsdoc function

* ... is a rest param w/array type in jsdoc function

* Simplify getTypeFromJSDocVariadicType
  • Loading branch information
sandersn authored Mar 22, 2018
1 parent ca1d19a commit e16bb3e
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 2 deletions.
12 changes: 11 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24548,8 +24548,15 @@ namespace ts {
checkJSDocTypeIsInJsFile(node);
checkSourceElement(node.type);

// Only legal location is in the *last* parameter tag.
// Only legal location is in the *last* parameter tag or last parameter of a JSDoc function.
const { parent } = node;
if (isParameter(parent) && isJSDocFunctionType(parent.parent)) {
if (last(parent.parent.parameters) !== parent) {
error(node, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
}
return;
}

if (!isJSDocTypeExpression(parent)) {
error(node, Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature);
}
Expand Down Expand Up @@ -24595,6 +24602,9 @@ namespace ts {
}
}
}
if (isParameter(parent) && isJSDocFunctionType(parent.parent)) {
return createArrayType(type);
}
return addOptionality(type);
}

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1861,7 +1861,7 @@ namespace ts {
}

export function isRestParameter(node: ParameterDeclaration): boolean {
return node.dotDotDotToken !== undefined;
return node.dotDotDotToken !== undefined || node.type && node.type.kind === SyntaxKind.JSDocVariadicType;
}

export const enum AssignmentKind {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
=== tests/cases/conformance/jsdoc/a.js ===
// from bcryptjs
/** @param {function(...[*])} callback */
function g(callback) {
>g : Symbol(g, Decl(a.js, 0, 0))
>callback : Symbol(callback, Decl(a.js, 2, 11))

callback([1], [2], [3])
>callback : Symbol(callback, Decl(a.js, 2, 11))
}

/**
* @type {!function(...number):string}
* @inner
*/
var stringFromCharCode = String.fromCharCode;
>stringFromCharCode : Symbol(stringFromCharCode, Decl(a.js, 10, 3))
>String.fromCharCode : Symbol(StringConstructor.fromCharCode, Decl(lib.d.ts, --, --))
>String : Symbol(String, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>fromCharCode : Symbol(StringConstructor.fromCharCode, Decl(lib.d.ts, --, --))

28 changes: 28 additions & 0 deletions tests/baselines/reference/jsdocParseDotDotDotInJSDocFunction.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
=== tests/cases/conformance/jsdoc/a.js ===
// from bcryptjs
/** @param {function(...[*])} callback */
function g(callback) {
>g : (callback: (...arg0: [any][]) => any) => void
>callback : (...arg0: [any][]) => any

callback([1], [2], [3])
>callback([1], [2], [3]) : any
>callback : (...arg0: [any][]) => any
>[1] : [number]
>1 : 1
>[2] : [number]
>2 : 2
>[3] : [number]
>3 : 3
}

/**
* @type {!function(...number):string}
* @inner
*/
var stringFromCharCode = String.fromCharCode;
>stringFromCharCode : (...arg0: number[]) => string
>String.fromCharCode : (...codes: number[]) => string
>String : StringConstructor
>fromCharCode : (...codes: number[]) => string

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @noEmit: true
// @allowJs: true
// @checkJs: true
// @strict: true
// @Filename: a.js

// from bcryptjs
/** @param {function(...[*])} callback */
function g(callback) {
callback([1], [2], [3])
}

/**
* @type {!function(...number):string}
* @inner
*/
var stringFromCharCode = String.fromCharCode;

0 comments on commit e16bb3e

Please sign in to comment.