Search Terms
- jsdoc import
- import *
- import namespace
- jsdoc namespace
Suggestion
Provide a JSDoc equivalent of import * as Sub from "./sub" so that types & interfaces from the ./sub module could be referenced as Sub.Type, Sub.Interface.
I have no preference in terms of actual syntax, but in my experience general expectation had been that following syntax should do just that (but it is not and I can't seem to figure out what does Sub results in here:
@typedef {import('./sub')} Sub
If above is not a viable options maybe using same * character could be an options:
@typedef {import('./sub').*} Sub
Or maybe whole new @import jsdoc tag.
Use Cases
js-ipfs (fairly large code base) has adopted TS via JSDoc syntax but dealing with large number of imported types & interfaces from other modules had been a major source of pain for following reasons:
- Every single type requires
@typedef {import('...').Name} Alias.
- Importing generic types / interfaces requires repeating type parameters via
@template tags
- Which is error prone because when omitted it turns into
any
- Ends up require lot of typing
- Changes to library layout requires updating all those typdefs all over the code base (and vscode can't help there sadly)
- Alternative is to consolidating them in one place, but then vscode (and alike) takes multiple hops / clicks to get you to actual type definition.
All of the above make otherwise mostly good experience to be painful.
Current approach also has side effect of turning imported interfaces into types (see #41258) which than can't be used in implements syntax as they are no longer interfaces.
Given that it is possible to do import * as Sub from "./sub" to get a namespace of exports in TS syntax it seems like equivalent in jsdoc syntax would:
- Allow reduced number of
@typedef {import(...).Name} Name declarations.
- Allow importing generic types without having to retype type parameters via
@temaplate tags.
- Avoid turning interfaces.
Examples
Consider following TS code:
import { BlockEncoder, BlockDecoder } from "@multiformats/codecs"
import { DagNode } form "./node"
class DagPB implements BlockEncoder<0x70, DagNode>, BlockDecoder<0x70, DagNode> {
async encode(node:DagNode):Promise<Uint8Array> {
// ...
}
async decode(bytes:Uint8Array):Promise<DagNode> {
// ...
}
}
Same code with JSDoc syntax turns into following:
/**
* @template {number} Code
* @template T
* @typedef {import('@multiformats/codecs').BlockEncoder<Code, T>} BlockEncoder
*/
/**
* @template {number} Code
* @template T
* @typedef {import('@multiformats/codecs').BlockDecoder<Code, T>} BlockDecoder
*/
/**
* @typedef {import("./node").DagNode} DagNode
*/
/**
* @implements {BlockEncoder<0x70, DagNode>}
* @implements {BlockDecoder<0x70, DagNode>}
*/
class DagPB {
/**
* @param {DagNode} node
* @returns {Promise<Uint8Array>}
*/
async encode(node) {
// ...
}
/**
* @param {Uint8Array} bytes
* @returns {Promise<DagNode>}
*/
async decode(bytes) {
// ...
}
}
Note: Above code won't even produce desired typedefs due to #41258
And now if we had what this issue proposes it would be:
/**
* @typedef {import('@multiformats/codecs')} Codec
* @typedef {import('./node').DagNode} DagNode
*/
/**
* @implements {Codec.BlockEncoder<0x70, DagNode>}
* @implements {Codec.BlockDecoder<0x70, DagNode>}
*/
class DagPB {
/**
* @param {DagNode} node
* @returns {Promise<Uint8Array>}
*/
async encode(node) {
// ...
}
/**
* @param {Uint8Array} bytes
* @returns {Promise<DagNode>}
*/
async decode(bytes) {
// ...
}
}
Checklist
My suggestion meets these guidelines:
Search Terms
Suggestion
Provide a JSDoc equivalent of
import * as Sub from "./sub"so that types & interfaces from the./submodule could be referenced asSub.Type,Sub.Interface.I have no preference in terms of actual syntax, but in my experience general expectation had been that following syntax should do just that (but it is not and I can't seem to figure out what does
Subresults in here:If above is not a viable options maybe using same
*character could be an options:Or maybe whole new
@importjsdoc tag.Use Cases
js-ipfs (fairly large code base) has adopted TS via JSDoc syntax but dealing with large number of imported types & interfaces from other modules had been a major source of pain for following reasons:
@typedef {import('...').Name} Alias.@templatetagsanyAll of the above make otherwise mostly good experience to be painful.
Current approach also has side effect of turning imported interfaces into types (see #41258) which than can't be used in
implementssyntax as they are no longer interfaces.Given that it is possible to do
import * as Sub from "./sub"to get a namespace of exports in TS syntax it seems like equivalent in jsdoc syntax would:@typedef {import(...).Name} Namedeclarations.@temaplatetags.Examples
Consider following TS code:
Same code with JSDoc syntax turns into following:
Note: Above code won't even produce desired typedefs due to #41258
And now if we had what this issue proposes it would be:
Checklist
My suggestion meets these guidelines: