Skip to content

Commit

Permalink
feat(type-formatter): support rest parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment committed Feb 3, 2021
1 parent a4de195 commit 9952ab8
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 2 deletions.
31 changes: 29 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,41 @@ function formatType(type: string, options?: Options): string {
try {
const TYPE_START = "type name = ";

let pretty = format(`${TYPE_START}${type}`, {
let pretty = type;

// Rest parameter types start with "...". This is supported by TS and JSDoc
// but it's implemented in a weird way in TS. TS will only acknowledge the
// "..." if the function parameter is a rest parameter. In this case, TS
// will interpret `...T` as `T[]`. But we can't just convert "..." to arrays
// because of @callback types. In @callback types `...T` and `T[]` are not
// equivalent, so we have to support "..." as is.
//
// This formatting itself is rather simple. If `...T` is detected, it will
// be replaced with `T[]` and formatted. At the end, the outer array will
// be removed and "..." will be added again.
//
// As a consequence, union types will get an additional pair of parentheses
// (e.g. `...A|B` -> `...(A|B)`). This is technically unnecessary but it
// makes the operator precedence very clear.
//
// https://www.typescriptlang.org/docs/handbook/functions.html#rest-parameters
let rest = false;
if (pretty.startsWith("...")) {
rest = true;
pretty = `(${pretty.slice(3)})[]`;
}

pretty = format(`${TYPE_START}${pretty}`, {
...options,
parser: "typescript",
});
pretty = pretty.slice(TYPE_START.length);

pretty = pretty.replace(/[;\n]*$/g, "");

if (rest) {
pretty = "..." + pretty.replace(/\[\s*\]$/, "");
}

return pretty;
} catch (error) {
// console.log("jsdoc-parser", error);
Expand Down
11 changes: 11 additions & 0 deletions tests/__snapshots__/main.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ exports[`Empty comment 1`] = `
"
`;

exports[`Format rest parameters properly 1`] = `
"/**
* @param {...any} arg1
* @param {...number} arg2
* @param {...(string | number)} arg3
* @param {...(string | number)} arg4 This is equivalent to arg3
*/
function a() {}
"
`;

exports[`Hyphen at the start of description 1`] = `
"/**
* Assign the project to an employee.
Expand Down
15 changes: 15 additions & 0 deletions tests/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,3 +427,18 @@ test("Non-jsdoc comment", () => {

expect(result).toMatchSnapshot();
});

test("Format rest parameters properly", () => {
const result = subject(`
/**
* @param {... *} arg1
* @param {... number} arg2
* @param {... (string|number)} arg3
* @param {... string|number} arg4 This is equivalent to arg3
*
*/
function a(){}
`);

expect(result).toMatchSnapshot();
});

0 comments on commit 9952ab8

Please sign in to comment.