-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Circular reference error happens in jsdoc but not in typescript. #46369
Comments
I have the same issue. |
Same here (using TS 4.6.3). |
The workaround is to use TypeScript in the JSDoc comment, rather than /**
* @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 /**
* @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
*/ 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
/** @typedef {Object.<string, Foo>} Foo */
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.The text was updated successfully, but these errors were encountered: