otris / jsdoc-tsd

JSDoc template for generating TypeScript definition files based on JSDoc comments.
MIT License
29 stars 7 forks source link

module-based namepaths result in wrong name in TSD #39

Closed whitlockjc closed 6 years ago

whitlockjc commented 6 years ago

Let's say I have a @module with an inner @typedef:

/**
 * @module my-module
 */

/**
 * @typedef {object} MyType
 */

If I wanted to pass MyType as a @param to a function or as a @property of another @typedef, based on JSDoc convention you should use a namepath whenever using modules like this:

/**
 * My function:
 *
 * @param {module:my-module~MyType} obj - The object
 */
module.exports.myFunc = function (obj) {
  // ...
}

jsdoc and related templates (like the template to convert to markdown) handle this properly but whenever @otris/jsdoc-tsd generates the TSD, I get something like this:

declare module 'my-module' {
  declare interface MyType {}

  export function myFunc(obj: module:my-module~MyType): void;
}

So instead of obj: MyType, I get obj: module:my-module~MyType. The same thing happens when you use a namepath for any other place where a namepath is used, like @property.

The reason this has come up is that my JSDoc either generates proper TSD (via @otris/jsdoc-tsd) or MD (via jsdoc2md/jsdoc-to-markdown) but never both at the same time. I realize that jsdoc2md/jsdoc-to-markdown could very well be the culprit but when I looked into this from the JSDoc site, it looks like any namepath should be fully-qualified when using modules.

whitlockjc commented 6 years ago

Here is a workaround where I updated my JSDoc to use appropriate namepaths, for jsdoc2md/jsdoc-to-markdown, and a Gulp task that will fix the invalid TSD generated as a result: https://github.com/whitlockjc/path-loader/commit/0d459ac327685b4e6d613a4c26b9a8669ea1bb3f This also addressed #38 as well.

wehrstedt commented 6 years ago

Like you have mentioned, this module currently has problem in general with full qualified namepaths. The issue is in function mapVariableType.

To fix this, we need to implement a mechanism which resolve the passed namepath to an already parsed type definition. Therefore you need to search for the requested item in the private member jsdocItems of the JSDocTsdParser-class.

One thing to note: If the type definition of the used type comes after the declaration, the fix won't work. To make it clear with your example

/**
 * My function:
 *
 * @param {module:my-module~MyType} obj - The object
 */
module.exports.myFunc = function (obj) {
  // ...
}

/**
 * @module my-module
 */

/**
 * @typedef {object} MyType
 */

this code won't work because the definition of MyType has to be before the definiiton of myFunc. That's another problem we have to think about.

Summarized:

  1. Create a lookup mechanism
  2. Reorder the input of the jsdoc-module (new issue)
tineheller commented 6 years ago

I think this is finished with PR #40. There are only some tests to implement and a little problem to clarify, but I created new issues for that (#43 and #44).