TypeScript Version: 3.8.3
Search Terms: jsDoc callback
Expected behavior: I'm attempting to generate TS definition files from a fairly large JavaScript codebase that makes meticulous use of JSDoc comments. I ran into an issue with JSDoc style callback definitions, which rely on the tilde, ~. Basically, TS should interpret the callback correctly and produce valid definitions. For my sample code, I would expect something like the below:
export default TextureAtlas;
export type TextureAtlasCreateImageCallback = () => any;
/**
* @alias TextureAtlas
* @constructor
*/
declare function TextureAtlas(options: any): void;
declare class TextureAtlas {
/**
* @alias TextureAtlas
* @constructor
*/
constructor(options: any);
passCallback(callback: TextureAtlasCreateImageCallback): any;
}
Or even better, make CreateImageCallback a member of TextureAtlas
Actual behavior: It outputs invalid TS code that truncates the callback name
export default TextureAtlas;
/**
* ~CreateImageCallback
*/
export type TextureAtlas = () => any;
/**
* @alias TextureAtlas
* @constructor
*/
declare function TextureAtlas(options: any): void;
declare class TextureAtlas {
/**
* @alias TextureAtlas
* @constructor
*/
constructor(options: any);
passCallback(callback: any): any;
}
Removing the ~ from the source JS code and JSDoc dramatically changes the output.
Related Issues: No
Code
/**
* @alias TextureAtlas
* @constructor
*/
function TextureAtlas(options) {
}
/**
* @param {TextureAtlas~CreateImageCallback} callback
*/
TextureAtlas.prototype.passCallback = function(callback) {
return callback();
}
/**
* @callback TextureAtlas~CreateImageCallback
* @returns {Image} The image
*/
export default TextureAtlas;
Output
export default TextureAtlas;
/**
* ~CreateImageCallback
*/
export type TextureAtlas = () => any;
/**
* @alias TextureAtlas
* @constructor
*/
declare function TextureAtlas(options: any): void;
declare class TextureAtlas {
/**
* @alias TextureAtlas
* @constructor
*/
constructor(options: any);
passCallback(callback: any): any;
}
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"useDefineForClassFields": false,
"alwaysStrict": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"downlevelIteration": false,
"noEmitHelpers": false,
"noLib": false,
"noStrictGenericChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"esModuleInterop": true,
"preserveConstEnums": false,
"removeComments": false,
"skipLibCheck": false,
"checkJs": true,
"allowJs": true,
"declaration": true,
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
"target": "ES5",
"module": "ES2015"
}
}
Playground Link: Provided
@RyanCavanaugh we very explicitly do not support jsdoc namepaths (beyond instructing the parser how to skip over them), and Thing~Whatever is definitely a jsdoc namepath.
Thanks @weswigham so I assume that means this will not be supported anytime soon? I just found it odd that it generates invalid TS and doesn't output any kind of warnings (but I'm relatively new to TS so I still have a lot to learn).
The documentation (https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#supported-jsdoc) doesn't say anything about namepaths, just that @callback is explicitly supported. So it would be nice if it were updated to reflect JSDoc limitations more completely.
Is there any recommendation on how to modify our use of JSDoc to better accommodate the TS compiler? Simply removing the ~ character sort of works because it turns it into a global callback function, but it changes the doc output in non-trivial ways.
Write the TS-compatible type references that refer to things instead - usually NamespaceThing.ExportWhatever for lookups/declarations, but ClassThing["instance member"], and import("mod").ExportThing may also be useful for looking up things.
Thanks, I can't believe I didn't notice that replacing ~ with . worked (with seemingly no ill affects on the jsDoc side).