如何使用JSDoc的@typedef定义允许存在未知属性的不完整对象类型?
如何使用JSDoc的@typedef定义允许存在未知属性的不完整对象类型?
这问题我之前在项目里也碰到过,刚好有几个靠谱的解决办法,既能满足你用JSDoc定义类型的需求,又能让TypeScript的类型检查不报错,而且完全是合法的JS代码,不会有问题~
方法一:给类型添加索引签名
最直接的方式就是在你的@typedef定义里加上索引签名,明确告诉TypeScript这个类型的对象允许存在任意额外的字符串键属性。
示例代码:
// @ts-check /** * @typedef {Object} Message * @property {string} sender // 已知属性:发送方 * @property {string} receiver // 已知属性:接收方 * @property {any} [key: string] // 允许任意字符串键的未知属性,值类型设为any */ /** @type {Message} */ let msg = { sender: "preference-manager", receiver: "user-manager", deletePref: "refresh-rate" }
这里的[key: string]: any就是核心:它表示这个类型的对象可以有任意数量的字符串类型的键,对应的值可以是任意类型。如果你想限制未知属性的值类型(比如只能是字符串),直接把any改成string就可以,TypeScript会帮你做对应的类型检查。
方法二:用交叉类型组合已知属性和任意键值对
如果你觉得在@typedef里写索引签名不够直观,还可以用交叉类型,把你定义的已知属性对象和Record<string, any>(代表任意键值对的内置类型)组合起来。
示例代码:
// @ts-check /** * @typedef { { sender: string; receiver: string } & Record<string, any> } Message */ /** @type {Message} */ let msg = { sender: "preference-manager", receiver: "user-manager", deletePref: "refresh-rate" }
这种写法的好处是把已知属性的定义和“允许未知属性”的规则分开,逻辑更清晰。同样,你可以把Record<string, any>里的any换成具体类型,来限制未知属性的值类型。
额外提醒
这两种方法都完全符合纯JS的语法规范,不会影响代码的运行,只是给TypeScript的类型检查器提供了更准确的类型信息,刚好匹配你既要类型安全又要合法JS的需求。
内容来源于stack exchange
相关产品推荐
相关产品推荐

