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?
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.