如何用JSDoc为含动态键的对象实现类型提示(非TypeScript环境)
如何用JSDoc为含动态键的对象实现类型提示(非TypeScript环境)
看起来你已经在尝试用JSDoc给带动态键的对象做类型提示,但遇到了IDE无法推断属性的问题——我来帮你梳理下问题出在哪,以及怎么解决。
首先,你试过的两种写法都没得到预期的补全效果:
第一种写法输入example.时没有任何属性提示:
第二种用类模拟类型的写法也同样无效:
不过你也确认了基础的类型推断是正常的,这说明你的IDE配置没问题,只是JSDoc的语法细节没处理对:
问题根源:JSDoc类型定义语法错误
你之前的SomeOther类型用@type来声明属性是错误的用法,@typedef定义对象结构时,应该用@property来指定每个属性的类型。另外,动态键的索引签名在JSDoc里有更兼容的标准写法。
正确的实现方式
我们先修正类型定义,就能得到正常的类型提示了:
方法一:直接用索引签名定义动态对象类型
/** * @typedef {Object} SomeOther * @property {string} a - 字符串类型的属性a * @property {boolean} c - 布尔类型的属性c * @property {number} d - 数字类型的属性d */ /** * 用JSDoc的标准语法定义动态键对象 * 写法1:Object.<string, SomeOther> * 写法2:Record<string, SomeOther>(更现代,主流IDE都支持) * @typedef {Record<string, SomeOther>} Dynamic */ /** * @param {Dynamic} arg */ const foo = (arg) => { const example = arg['foo']; example. // 现在这里应该能看到a、c、d的自动补全了 };
方法二:用类来模拟类型提示(修正版)
如果你偏好类的方式,需要给类添加正确的索引签名JSDoc:
/** * @typedef {Object} SomeOther * @property {string} a * @property {boolean} c * @property {number} d */ /** * @class * 给类添加索引签名,表明任意字符串键对应的都是SomeOther类型 * @property {SomeOther} [key: string] */ class ClassAsTypehint {} /** * @param {ClassAsTypehint} arg */ const foo = (arg) => { const example = arg['foo']; example. // 现在可以正常看到属性补全了 };
为什么之前的写法无效?
SomeOther类型定义错误:你用@type来给@typedef的对象声明属性,这不符合JSDoc的规范,必须用@property来定义对象的属性结构。- 索引签名写法兼容性问题:
{[key: string]: SomeOther}是TypeScript的语法,虽然部分IDE可能支持,但JSDoc更标准的写法是Object.<string, SomeOther>或者Record<string, SomeOther>,后者是ES6之后的语法,现在主流IDE(包括PhpStorm)都能完美识别。
这样修改后,你的IDE应该就能正确识别动态键对象的属性类型,提供对应的自动补全和类型提示了。
备注:内容来源于stack exchange,提问作者k0pernikus
相关产品推荐
相关产品推荐

