使用tsc生成JS库声明文件时,如何包含JSDoc中的动态属性?
解决方案:为动态添加属性的类生成完整TypeScript声明文件
方法1:手动编写声明文件(推荐)
自动生成工具无法识别通过Object.defineProperty动态添加的属性,最可靠的方式是直接手写.d.ts声明文件:
// types/ExampleClass.d.ts export declare class ExampleClass { realProperty: number; fakeProperty: number; /** * Creates the class * @param inputNumber the number to store */ constructor(inputNumber: number); }
之后运行tsc时,TypeScript会优先使用手动编写的声明文件,而非自动生成的版本。
方法2:在JS类中添加虚拟属性(适配自动生成流程)
如果需要保留自动生成声明的流程,可以在类的构造函数中添加一个虚拟的fakeProperty赋值,并用// @ts-ignore忽略运行时无关的报错,这样tsc会将该属性纳入生成的声明中:
/** * Example class * @property {Number} realProperty - Is actually defined in the code * @property {Number} fakeProperty - Not actually present in the code */ export class ExampleClass { /** * Creates the class * @param {Number} inputNumber the number to store */ constructor (inputNumber) { this.realProperty = inputNumber; // 虚拟赋值,用于让tsc识别该属性,实际运行时由Object.defineProperty覆盖 // @ts-ignore this.fakeProperty = 0; } }
重新运行你的tsc命令:
tsc index.js --declaration --allowJs --emitDeclarationOnly --outDir types
生成的声明文件会同时包含realProperty和fakeProperty。
方法3:用JSDoc扩展类类型
在JS文件中通过JSDoc的@interface和@augments来扩展类的类型定义,确保TypeScript能识别动态添加的属性:
/** * Example class * @property {Number} realProperty - Is actually defined in the code */ export class ExampleClass { /** * Creates the class * @param {Number} inputNumber the number to store */ constructor (inputNumber) { this.realProperty = inputNumber; } } /** * @augments ExampleClass */ interface ExampleClass { fakeProperty: number; }
这种方式不需要修改类的内部逻辑,仅通过JSDoc扩展类型,也能让tsc生成包含fakeProperty的声明文件。
内容的提问来源于stack exchange,提问作者Daniel Hurtado Ramirez
相关产品推荐
相关产品推荐

