TypeScript Version: 3.3.0-dev.20190118
Search Terms: jsdoc import module.exports has no exported member
Code
a.js
class A {}
module.exports = {A}
b.js
// @ts-check
class B {
// In the JSDoc below, VSCode intellisense does not recognize parameter a as type A.
// Instead it shows the error:
// Namespace '".../a".export=' has no exported member 'A'
/**
* @param {import('./a').A} a
*/
constructor (a) {
this.a = a
}
}
Expected behavior
Parameter a of the constructor should be recognized as type A, which is accessible via the A property of module.exports from a.js.
Actual behavior
Intellisense reports the error: Namespace '".../a".export=' has no exported member 'A'.
Notes
@param {import('./a')} a does not give an error, but it resolves to type {A: typeof A} instead of A.
If a.js is modified with module.exports = A, then import('./a') resolves to A, however this restricts a.js to only exporting one type.
This bug is currently blocking our team from adopting ts-check into our Javascript codebase, as we have .js files that export classes, and those classes can't be used in our ts-checked files until this bug is resolved.
As a workaround, we could define our own .d.ts files for the modules in question, but this is a lot of what we feel is duplicate work - the types are already defined in jsdoc format inline in the files.
I also had problems with this. A workaround which I have (unfortunately) used is:
InstanceType<import('./a')['A']>
import('./a')['A'] has type typeof A (i.e. the type of the class), so InstanceType<> needs to be used to get the instance
However I would much prefer it to work as import('./a').A
I have found that using exports.Thing = Thing is recognized properly, while using
module.exports = { Thing };
is not.
Most helpful comment
I also had problems with this. A workaround which I have (unfortunately) used is:
import('./a')['A']has typetypeof A(i.e. the type of the class), soInstanceType<>needs to be used to get the instanceHowever I would much prefer it to work as
import('./a').A