-
Notifications
You must be signed in to change notification settings - Fork 702
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
Parent class referenced via symbol of type "typeof Parent" not included in class hierarchy #2775
Comments
This is going to be a wontfix/design limitation. TypeDoc relies on the symbol to link parent/children classes and properties/variables introduce a new symbol which cannot be reliably linked to the real class. It also isn't generally safe to rely on |
Hmm, ok, thanks for confirming. Correct me if I'm mistaken, there's no other way in TypeScript to indicate that some property holds a class (so that TypeDoc would be able to reference it), right? |
Without introducing a new symbol, I'm not aware of any. If you don't care about the safety issue, you could use a plugin to re-point references to the property to the originating class... npx typedoc src/gh2775.d.ts --plugin ./plugins/gh2775.js // CC0
import td, { Converter, ReflectionKind } from "typedoc";
/** @param {td.Application} app */
export function load(app) {
app.converter.on(
Converter.EVENT_RESOLVE_BEGIN,
(context) => {
for (const decl of context.project.getReflectionsByKind(ReflectionKind.ClassOrInterface)) {
hackInheritance(decl);
}
},
1e6,
);
}
/** @param {td.DeclarationReflection} decl */
function hackInheritance(decl) {
if (!decl.extendedTypes) return;
for (let i = 0; i < decl.extendedTypes.length; ++i) {
const type = decl.extendedTypes[i];
if (type.type !== "reference") continue;
if (!type.reflection) continue;
/** @type {td.DeclarationReflection} */
const target = type.reflection;
if (target.kindOf(ReflectionKind.ClassOrInterface)) continue;
const targetType = target.type;
if (targetType.type !== "query") continue;
if (!targetType.queryType.reflection?.kindOf(ReflectionKind.ClassOrInterface)) continue;
// We inherit from a property somewhere which is declared as `typeof SomeClass`
// So re-point the inheritance to SomeClass
decl.extendedTypes[i] = targetType.queryType;
}
} |
Yeah I thought so. Thanks again for the quick reply : ) That hack does what it's intended to do.
I do care, in general, about (type) safety (but also about nice docs for users). If you don't mind me asking, what case did you have in mind where replacing |
I guess "safety" is a somewhat confusing term to use. The issue I see with including this in typedoc itself is: class Thing {
method() { return "a" }
}
class OtherThing {
method() { return "b" }
}
namespace Registry {
const Thing: typeof Thing = Math.random() > 0.5 ? Thing : OtherThing;
}
// Docs shouldn't mark Child as inheriting from Thing
class Child extends Registry.Thing {} |
I see, that's a good point, TypeScript doesn't have nominal types, so it considers classes with the same structure as equivalent. That's probably not an issue in most practical cases, but I agree, it's not correct in general. |
Search Terms
class hierarchy typeof parent
Problem
A very simple example:
In the generated documentation,
typeof A
and you can click on itBelow is a more elaborate example that shows what we're trying to do. The project consist of multiple different script files (with implicit dependencies) and linking between different script files is done via the global scope. So you you code like
class InputText extends PrimeFaces.widget.BaseWidget
primefaces/primefaces#12717Suggested Solution
Perhaps #2467 is related, but this seems like a different issue. I don't know how hard or easy it is to get class hierarchy information form TypeScript? Naively, I would imagine querying TypeScript for the type of the extends expression and checking if that is a known class.
More elaborate example
The text was updated successfully, but these errors were encountered: