question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@babel/plugin-transform-typescript strips vital JSDoc @typedef comments

See original GitHub issue

Bug Report


EDIT: See my comment https://github.com/babel/babel/issues/9916#issuecomment-489404010 below, there is a strange inconsistency depending on the location of import statements.


Running Babel with nothing but @babel/plugin-transform-typescript removes all but the very first of many JSDoc @typedef comments.

Those comments are for (and just above) Typescript type definitions (export type, export interface). When the Typescript types are stripped, so are the JSDoc comments. When I run jsdoc3 to generate the HTML API docs this tool too runs Babel and this plugin in order to be able to parse the file. Obviously, the removal of the JSDoc is counterproductive especially in this use case.

Environment

  • Babel version(s): 7.4.4

  • Node/npm version: 11.14

  • jsdoc 3.5.5

  • OS: Linux

  • How you are using Babel: jsdoc3, config (jsdoc.json, babel section):

"babel": {
        "extensions": ["js","ts","jsx","tsx"],
        "presets": ["@babel/preset-typescript"],
        "plugins": [],
        "babelrc": false
    },

Example

Here is an excerpt of the beginning of a file with many TS type definitions and there accompanying JSDoc comments.

/**
 * This defines the creation status string constants for files
 * @global
 * @typedef {("new"|"exists")} FileCreationStatus
 */
export type FileCreationStatus = typeof CREATION_STATUS[keyof typeof CREATION_STATUS];

/**
 * @global
 * @typedef {Object} FileCreation
 * @property {SHA256Hash} hash - The SHA-256 hash of the contents of a versioned ONE object
 * @property {FileCreationStatus} status - A string constant showing whether the file
 * already existed or if it had to be created.
 */
export interface FileCreation {
    hash: SHA256Hash;
    status: FileCreationStatus;
}

/**
 * This defines the creation status string constants for objects.
 * @global
 * @typedef {FileCreationStatus} ObjectCreationStatus
 */
export type ObjectCreationStatus = FileCreationStatus;

After the transformation only this is left of these comments:

/**
 * This defines the creation status string constants for files
 * @global
 * @typedef {("new"|"exists")} FileCreationStatus
 */
export type FileCreationStatus = typeof CREATION_STATUS[keyof typeof CREATION_STATUS];

Lots and lots of comments erased while there were nothing but Typescript type definitions encountered by the parser. Only when there was actual JS code again did the comment removal stop.

Proposed solution

Don’t delete any JSDoc (or any) comments. Comment removal should be left to the boolean “comment” Babel configuration property and whatever Babel code is following that instruction. If it is not set to true no comments should be removed, especially not JSDoc @typedef ones.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
lll000111commented, May 6, 2019

@nicolo-ribaudo I found something really weird, the issue is more complicated an nuanced. The comment removal is not always happening! If it was so simple as you show in the parser, the comment belong to the parsed statement so it’s removed, then it would be a reliable outcome, but it isn’t. It seems to be related to import statements, at least I can work around it by moving them, see last paragraph below.

Here is a Babel Repl example

Try either one of

  • Removing the last line
  • The first line with the import statement does it too
  • Move the import statement below the TS type definitions

With that import line all comments are gone as reported as my original problem. When that line is not there, all the comments are there all of a sudden!

I now moved all the import statements AFTER all the type definitions in all of my files. No comments are removed any more. This could work as a workaround, although to my mind at least it isn’t logical to have imports after exports (since the exports often use imported types) so my sense of order doesn’t like it 😃

Besides, I don’t like the randomness of this, the comment removals, I think there should at least be consistent behavior (to a normal human developer, of course, somewhere deep inside the parser’s bowels this is consistent).


UPDATE: I experimented with the plugin code, removing everything (that changes the AST) but

      TSInterfaceDeclaration(path) {
        path.remove();
      },

      TSTypeAliasDeclaration(path) {
        path.remove();
      },

and I still get this import statement location dependent behavior. So it isn’t in the plugin but deeper. IMO node removal should not deliver different results based on the location of import statements, that makes no sense to me.


Something else I just remembered probably worth mentioning: I recently switched from Flow to TypeScript, mostly just by renaming files *.js => *.ts. I never noticed anything previously, despite having had pretty much the same Babel workflow, only plugin flow-remove-types instead of the TypeScript plugin which also only removes types. This contradicts the previous paragraphs, where I find that cutting down the code in the TS plugin to just two plain removal statements (which surely flow-remove-types has two) makes no difference.


@pauloptimizely Thanks! I prefer the workaround I just found, see above, better than adding semicolons to my subjective feeling (and my IDE would disapprove about that too).

0reactions
lll000111commented, May 5, 2019

I’m curious: why do you need JSDoc comments in the compiled output?

I explain it in the second paragraph: I’m running jsdoc! To generate the HTML API docs! I need exactly the JSDoc! In that case the code itself actually doesn’t matter at all apart from those declarations that jsdoc uses.

Keep in mind that usually removing comments from a removed node is the right behavior,

There is a top-level babelrc setting for that!! If that is falseit is not the right behavior to remove comments.

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeScript strips down comments and spoils JSDoc ...
The question refers to JSDoc comments in the first place. They are indended for documentation readers who don't have to be code readers....
Read more >
Type Safe JavaScript with JSDoc - Medium
JSDoc comments are an alternative to TypeScript and Flow for type ... to JavaScript or a plugin to strip the comments out like...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found