Open jespertheend opened 3 years ago
I have the same issue.
Same here (using TS 4.6.3).
The workaround is to use TypeScript in the JSDoc comment, rather than Object.<string, Foo>
notation:
/**
* @typedef {{
* [x: string]: Foo
* }} Foo
*/
@jespertheend It doesn't work every time.
// TypeScript: OK
export type Json = null | boolean | number | string | Json[] | {[property: string]: Json};
// JavaScript: error 2456
/**
* @typedef {null | boolean | number | string | Json[] | {[property: string]: Json}} Json
*/
Seems like that's because Json[]
is also in there. Another way to work around this is to add an extra type just for the array:
/**
* @typedef {null | boolean | number | string | JsonArray | {[property: string]: Json}} Json
*/
/** @typedef {Json[]} JsonArray */
I wrote a little template typedef to help creating circular references:
/**
* @typedef {T | CircularArray<T> | CircularObject<T>} Circular
* @template T
*/
/**
* @typedef {Circular<T>[]} CircularArray
* @template T
*/
/**
* @typedef {{[key: string]: Circular<T>}} CircularObject
* @template T
*/
/**
* @typedef {Circular<number | string>} NumberStringObject
*/
/** @type {NumberStringObject} */
const x = {
y: [1, {z: [1, 2, 3]}]
}
Another example, lets say you have a type like this:
/**
* @typedef {{destroy: Function} | HTMLElement | Destroyable[] | undefined | null} Destroyable
*/
Error:
Solution:
/**
* @typedef {T | CircularArray<T>} Circular
* @template T
*/
/**
* @typedef {Circular<T>[]} CircularArray
* @template T
*/
/**
* @typedef {{destroy: Function} | HTMLElement | undefined | null} DestroyableTypes
*/
/**
* @typedef {Circular<DestroyableTypes>} Destroyable
*/
/**
* @param {Destroyable} o
*/
export function destroy(o) {
if (!o) {
return;
}
// Order of most to least specific types (every array is an object, but not vice versa)
if (o instanceof Array) {
// Destroy an array by destroying every component recursively and setting length to 0
o.forEach(destroy);
o.length = 0;
} else if (o instanceof HTMLElement) {
// TODO: maybe remove() with Removeable instead?
o.remove();
} else if (o instanceof Object && typeof o.destroy === "function") {
o.destroy();
} else {
console.warn('destroy has no function for type', typeof o);
}
}
const data = [{
destroy() {
console.log("oh no");
}
}, {
destroy() {
console.log("aaaahhh");
}
}, [
{
topkek() {
console.log("grrraaaaaaaaaahh"); // console warns> destroy has no function for type object
}
}, {
destroy() {
console.log("*dies in silence*");
}
}
]];
destroy(data);
Bug Report
🔎 Search Terms
circularly references itself jsdoc ts2456
🕗 Version & Regression Information
circular
⏯ Playground Link
Playground link (js) Playground link (ts)
💻 Code
Foo.js
Foo.ts
🙁 Actual behavior
Type alias 'Foo' circularly references itself. ts(2456)
happens inFoo.js
. The TypeScript equivalent works fine.🙂 Expected behavior
Both
Foo.ts
andFoo.js
work without errors.Related issues
I found some related issues but they are either closed or use a different example.
39372 - Closed (fixed)
45641 - Seems very similar but uses
Array<>
and typescript rather than jsdoc. I'm not sure if the root cause is the same so this might be a duplicate.