Reputation: 7617
The JSDoc api says you can document objects like so:
{Object.<string, number>}
and document multiple type:
{(number|boolean)}
But if I try to specify an object that could have strings OR numbers as the key, it does not work. VSCode/JSDoc just reports the type as 'any'.
VSCode does not understand:
/**
* Object with string or number for keys
* @param {Object.<(string|number), any>} Container
*/
I've also tried this in @typedef
, or defining the key in it's own @typedef
to no effect.
Because I'm using &
to get an intersection
of types (like {Object.<string, any> & {'foo': number}}
I don't want to have to use the boolean or to say:
/**
* Object with string or number for keys
* @param {(Object.<string, any>|Object.<number, any>) & {'foo': number}} Container
*/
The type documented ends up looking something like:
type Container = ({
[x: string]: any;
} & {
'foo': number;
}) | ({
[x: number]: any;
} & {
'foo': number;
})
Which is needlessly verbose.
Is there way to document this with a more succinct output?
Upvotes: 15
Views: 11973
Reputation: 3589
In JavaScript, object keys are always strings (or, in the case of numbers, coerced into strings), so you might be needlessly complicating things. See the ECMAScript spec on Objects:
Properties are identified using key values. A property key value is either an ECMAScript String value or a Symbol value. All String and Symbol values, including the empty String, are valid as property keys. A property name is a property key that is a String value.
An integer index is a String-valued property key that is a canonical numeric String
That said, this seems like the most straightforward solution:
// Combined
/**
* @param {Object.<string, any> & {foo: number}} Container
*/
// Split/reusable
/**
* @typedef {Object.<string, any>} GenericObject
* @param {GenericObject & {foo: number}} Container
*/
Both of the above result in this type/documentation:
Container: {
[x: string]: any;
} & {
foo: number;
}
Declaring Object.<string, any>
seems a bit redundant to me since object keys are inherently string
s and values are inherently any
, so declaring it this way doesn't provide much value to a developer.
Upvotes: 16