Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the generated file compliant with dtslint #108

Closed
3 tasks
ggrossetie opened this issue Dec 28, 2019 · 4 comments
Closed
3 tasks

Make the generated file compliant with dtslint #108

ggrossetie opened this issue Dec 28, 2019 · 4 comments

Comments

@ggrossetie
Copy link
Contributor

Here's a simple example:

/**
 * @class Foo
 */
class Foo {
  /**
   * @returns {string} - The {string} bar
   */
  bar() {
    return 'bar'
  }
}

And here's the generated file:

types.d.ts

/**
 * @class Foo
 */
declare class Foo {
    /**
     * @returns {string} - The {string} bar
     */
    bar(): string;
}

Using dtslint:

$ dtslint types
Error: /path/to/types/types.d.ts:2:5
ERROR: 2:5   no-redundant-jsdoc          JSDoc tag '@class' is redundant in TypeScript code.
ERROR: 6:17  no-redundant-jsdoc          Type annotation in JSDoc is redundant in TypeScript code.
ERROR: 10:1  trim-file                   File should not end with a blank line. (Ending in one newline OK, ending in two newlines not OK.) See: https://github.com/Microsoft/dtslint/blob/master/docs/trim-file.md
ERROR: 11:1  no-consecutive-blank-lines  Consecutive blank lines are forbidden

As you can see we should do the following:

  • Remove redundant jsdoc tags @class, @namespace...
  • Remove type annotation {string}
  • Trim lines

And here's the expected result:

types.d.ts

/**
 */
declare class Foo {
    /**
     * @returns The {string} bar
     */
    bar(): string;
}
@englercj
Copy link
Owner

To do this we'd have to parse the jsdoc strings or generate our own based on the data we output. Both of which seem like a lot of work just to appease a style linter. I don't think this is worth it.

Also some of these seem like opinions. For example, I want all my files to end in a blank line.

@ggrossetie
Copy link
Contributor Author

To do this we'd have to parse the jsdoc strings or generate our own based on the data we output. Both of which seem like a lot of work just to appease a style linter.

I believe that we can generate the comment from the Doclet object right?
With the following example:

/**
 * The {Foo} class provides the most useful {#bar} function.
 * @class Foo
 */
class Foo {
  /**
   * An helper function to say hello.
   * @param {string|undefined} - An optional name (by default: 'World')
   * @returns {string} - a {string} that says "Hello" to the given name
   */
  hello(name = 'World') {
    return `Hello ${name}`
  }
}

I will get the following (simplified) Doclet objects:

Doclet {
  description: 'An helper function to say hello.',
  params:
   [ { description: 'An optional name (by default: \'World\')',
       name: 'name',
       defaultvalue: 'World' } ],
  returns:
   [ { type: [Object],
       description: '- a {string} that says "Hello" to the given name' } ]
}
Doclet {
  description: 'The {Foo} class provides the most useful {#bar} function.'
}

Here's an implementation (using template literals):

function handleComment<T extends ts.Node>(doclet: IDocletBase, node: T): T
{
    if (doclet.comment && doclet.comment.length > 4)
    {
        let description = '';
        if (doclet.description) {
          description = `\n * ${doclet.description}`;
        }

        let params = []
        if (doclet.params) {
          params = doclet.params.map((param) => `\n * @param ${param.description}`)
        }

        let returns = []
        if (doclet.returns) {
          returns = doclet.returns.map((ret) => `\n * @returns ${ret.description}`)
        }
        let comment = `*${description}${params.join('')}${returns.join('')}
 `

        const kind = ts.SyntaxKind.MultiLineCommentTrivia;

        ts.addSyntheticLeadingComment(node, kind, comment, true);
    }

    return node;
}

Also some of these seem like opinions.

Indeed, the official linter is opinionated.

For example, I want all my files to end in a blank line.

I don't mind removing a final blank line in a post task.
Arguably, I could also remove the extra JSDoc annotations in a post task using regular expressions but since JSDoc already parsed the comments I don't see why we couldn't use the Doclet object to generate a dtslint compliant comment.
JSDoc gives us structured data as opposed to
I also think that using regular expressions on the final output (ie. without any context) would be prone to errors.

If you don't want to change the current output, maybe we can enable this feature using a configuration file?

$ jsdoc -c dtslint-compliant-conf.json -t node_modules/tsd-jsdoc/dist

What do you think?

@englercj
Copy link
Owner

englercj commented Jan 2, 2020

If jsdoc gives us what we need I'm open to a PR that changes the coments to pass linting. I think taking a dts config file to modify output might be a bit overkill unless we find ourselves implementing many different workarounds.

@ggrossetie
Copy link
Contributor Author

Ok I'm working on it 👍

ggrossetie added a commit to ggrossetie/tsd-jsdoc that referenced this issue Jan 2, 2020
ggrossetie added a commit to ggrossetie/tsd-jsdoc that referenced this issue Jan 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants