如何为具有不同类型键的对象编写 JSDoc?

Posted

技术标签:

【中文标题】如何为具有不同类型键的对象编写 JSDoc?【英文标题】:How to write a JSDoc for an object with different types of keys? 【发布时间】:2022-01-06 14:28:16 【问题描述】:

JSDoc api 说你 can document objects 像这样:

Object.<string, number>

并记录多种类型:

(number|boolean)

但是,如果我尝试指定一个可以将字符串或数字作为键的对象,它就不起作用。 VSCode/JSDoc 只是将类型报告为“任何”。

VSCode 看不懂:

/**
 * Object with string or number for keys
 * @param Object.<(string|number), any> Container
 */

我也在@typedef 中尝试过,或者在它自己的@typedef 中定义密钥无效。

因为我使用&amp; 来获取intersection 类型(例如Object.&lt;string, any&gt; &amp; 'foo': number,所以我不想使用布尔值或说:

/**
 * Object with string or number for keys
 * @param (Object.<string, any>|Object.<number, any>) & 'foo': number Container
 */

记录的类型最终看起来像:

 type Container = (
    [x: string]: any;
   & 
    'foo': number;
  ) | (
    [x: number]: any;
   & 
    'foo': number;
  )

这是不必要的冗长。

有没有办法用更简洁的输出来记录这一点?

【问题讨论】:

【参考方案1】:

javascript 中,对象键始终是字符串(或者,对于数字,强制转换为字符串),因此您可能会不必要地使事情复杂化。见ECMAScript spec on Objects:

使用键值标识属性。属性键值是 ECMAScript 字符串值或符号值。所有字符串和符号值,包括空字符串,都可以作为属性键。属性名称是一个属性键,它是一个字符串值。

整数索引是一个字符串值的属性键,它是一个规范的数字字符串

也就是说,这似乎是最直接的解决方案:

// Combined
/**
 * @param Object.<string, any> & foo:  number Container
 */

// Split/reusable
/**
 * @typedef Object.<string, any> GenericObject
 * @param GenericObject & foo: number Container
 */

以上两种情况都会导致这种类型/文档:

Container: 
    [x: string]: any;
 & 
    foo: number;

声明Object.&lt;string, any&gt; 对我来说似乎有点多余,因为对象键本质上是strings,值本质上是any,因此以这种方式声明它不会为开发人员提供太多价值。

【讨论】:

以上是关于如何为具有不同类型键的对象编写 JSDoc?的主要内容,如果未能解决你的问题,请参考以下文章

如何为具有泛型类型的箭头函数编写流类型

如何为具有多种父类型的子场景编写 EF 代码优先映射

如何为解构对象中的嵌套函数编写类型?

如何为不同版本的 Xcode 编写条件

如何为包含特定函数数组的 JSON 对象编写接口

如何为 PyYAML 编写表示器?