这与问题30360391类似。我想表达的是,函数的参数是一个普通的 JS 对象,它可以具有任意属性(未知)名称,但所有属性都是具有固定属性的对象本身。
举个例子:功能就是这样
/**
* @param {Descriptor} desc
*/
function foo( desc ) {
// ...
}
典型的
desc
看起来像
desc = {
unknownEntity1: {
priority: 5,
writable: false,
},
unknownEntity2: {
priority: 42,
writable: true,
},
unknownEntity3: {
priority: 9,
writable: false,
}
}
我已经有了
/**
* @typedef {Object} DescriptorEntry
* @property {number} priority - The priority of the entity
* @property {boolean} writable - True, if the entity can be modified
*/
我仍然需要一个
typedef
来表示 Descriptor
,它基本上表示描述符是一个具有任意属性但都是 DescriptorEntry
类型的对象。作为伪代码,它会是这样的
/**
* @typedef {Object} Descriptor
* @property {DescriptorEntry} *
*/
当然,星号
*
作为“任何属性”的通配符是无效的Jsdoc语法。但我该如何正确做呢?
根据 https://jsdoc.app/tags-type.html ,从 JSDoc 3.2 开始,JSDoc 已完全支持 Google Closure Compiler 类型表达式。 https://jsdoc.app/tags-type.html#jsdoc-types 中描述了一种此类格式:
{Object.<string, number>}
因此,就您而言,您应该能够执行以下操作:
/**
* @typedef {Object.<string, DescriptorEntry>} Descriptor
*/
或者只是:
/**
* @typedef {{string, DescriptorEntry}} Descriptor
*/
如果您想要一个名为
string
或此类的特殊类型并详细说明允许的字符串值,您甚至可以将上面示例中的 DescriptorName
替换为其自己的类型。
但是有一点要注意。至少就我而言,虽然 JSDoc 不拒绝后一种格式,至少使用默认模板,但它仅将其显示为“对象”,没有任何特殊细节。然而,第一种格式显示正确。
这些是
PropertyDescriptor
和 PropertyDescriptorMap
的 Typescript 接口。 (PhpStorm 2020 也使用它们来完成代码):
TypeScript/lib/lib.es5.d.ts
interface PropertyDescriptor {
configurable?: boolean;
enumerable?: boolean;
value?: any;
writable?: boolean;
get?(): any;
set?(v: any): void;
}
interface PropertyDescriptorMap {
[s: string]: PropertyDescriptor;
}
您可以直接将它们用作
@type {}
或重新定义两者:
/**
* @typedef {Object} PropertyDescriptor
* @property {function(v: *): void} [set] - Set [name](v){...} 'accessor descriptor' only
* @property {function(): *} [get] - Get [name](){...} 'accessor descriptor' only
* @property {undefined|*} [value] - Value (primitive|func) valid in 'data descriptor' only
* @property {undefined|boolean} [writable] - Writable valid in 'data descriptor' only
* @property {undefined|boolean} [configurable] - Configurable valid in 'data && accessor - descriptor'
* @property {undefined|boolean} [enumerable] - Enumerable valid in 'data && accessor - descriptor'
*/
/**
* @typedef {Object<string,PropertyDescriptor>} PropertyDescriptorMap
*/
/**
* @type {PropertyDescriptor} myDescriptor
*/
let myDescriptor = {
configurable: true,
enumerable: true,
// value: {},
// writable: true,
get myGet(){},
set myGet(v){}
};