-
Notifications
You must be signed in to change notification settings - Fork 709
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
const
interpreted as function typed via an interface
declaration, yield unexpected comment summaries
#2521
Comments
I actually spent quite some time trying to fix this myself and I do have a fix, but it breaks ~30 regression tests: My approach involves:
I suspect I'm violating quite a few assumptions on how the reflections from other ASTs are supposed to look. |
This is, unfortunately, working as designed today. TypeDoc's stance historically has been that functions do not have comments, signatures do. This is at least partially because of the decision (from before me) to allow specifying comments on the implementation of overloads that would apply to any signatures that don't have a comment. This has been due for a redesign for a long time... it's probably time to do that. TypeDoc's current function rules are so convoluted that I have to rediscover them every time I have to deal with it, even if it's only been like a week... I think your idea to allow functions to have a comment is potentially the piece that was so obviously in front of my face that I've missed it for ages. (I actually much prefer the PR to add a failing test! It's easier for most people to just set up a project that I can clone, which the typedoc-repros project is meant to be) |
First off. Thanks a lot for stewarding and maintaining a valuable tool for the community!
I got that feeling too, when trying to wrap my head around the current implementation. If you're interested, I'd love to:
Feel free to pick any permutation of the above ... |
Thanks! I'm definitely interested in improving how this works.. unfortunately it's going to be a rather major change which will probably break >50% of TypeDoc's tests... and really needs to wait for a minor release to go with other breaking changes (0.26?) I suspect I'm going to have to just try to make the change and see what falls out of it in order to get a sense for how it'll go... I'm getting fairly close to being done with #2475, which is the other big thing I want to get into 0.26, so hopefully will be able to look at this in more detail next/nextnext weekend |
Yeah - it would probably be good to signal quite explicitly to developers, as they might have employed workarounds that could break (or are obsolete) after such a change.
That sounds great. It might not be that urgent, but I believe this is an important issue to get resolved nonetheless. Let me know if / how I can help as you progress 👍 |
Few weeks later than I wanted... but I finally spent some time looking at this today, and I think it's a promising way forward. The approach I'm taking is to formalize the difference between signature comments and symbol comments. Functions generally only have signature comments, but in the A very hacky attempt at this only requires three specs changes, and causes 11 tests to fail (working on the beta branch): The logic for how to decide whether a comment is a symbol or signature comment isn't quite right yet, but I suspect once that's nailed down this ought to actually be a pretty easy update (however, getting that right is likely going to be pretty tricky) Diffdiff --git a/src/lib/converter/comments/discovery.ts b/src/lib/converter/comments/discovery.ts
index e37a9b60..0fccce2e 100644
--- a/src/lib/converter/comments/discovery.ts
+++ b/src/lib/converter/comments/discovery.ts
@@ -190,7 +190,10 @@ export function discoverComment(
ts.SyntaxKind.MethodDeclaration,
ts.SyntaxKind.Constructor,
].includes(node.kind) &&
- !(node as ts.FunctionDeclaration).body
+ (symbol.declarations!.filter((d) =>
+ wantedKinds[kind].includes(d.kind),
+ ).length === 1 ||
+ !(node as ts.FunctionDeclaration).body)
) {
continue;
}
diff --git a/src/lib/converter/plugins/CommentPlugin.ts b/src/lib/converter/plugins/CommentPlugin.ts
index 07d1343f..ca61ba5f 100644
--- a/src/lib/converter/plugins/CommentPlugin.ts
+++ b/src/lib/converter/plugins/CommentPlugin.ts
@@ -364,19 +364,19 @@ export class CommentPlugin extends ConverterComponent {
}
if (reflection.type instanceof ReflectionType) {
- this.moveCommentToSignatures(
+ this.moveSignatureParamComments(
reflection,
reflection.type.declaration.getNonIndexSignatures(),
);
} else {
- this.moveCommentToSignatures(
+ this.moveSignatureParamComments(
reflection,
reflection.getNonIndexSignatures(),
);
}
}
- private moveCommentToSignatures(
+ private moveSignatureParamComments(
reflection: DeclarationReflection,
signatures: SignatureReflection[],
) {
@@ -384,13 +384,9 @@ export class CommentPlugin extends ConverterComponent {
return;
}
- const comment = reflection.kindOf(ReflectionKind.ClassOrInterface)
- ? undefined
- : reflection.comment;
-
for (const signature of signatures) {
const signatureHadOwnComment = !!signature.comment;
- const childComment = (signature.comment ||= comment?.clone());
+ const childComment = signature.comment;
if (!childComment) continue;
signature.parameters?.forEach((parameter, index) => {
@@ -440,40 +436,17 @@ export class CommentPlugin extends ConverterComponent {
}
}
- this.validateParamTags(
- signature,
- childComment,
- signature.parameters || [],
- signatureHadOwnComment,
- );
-
- childComment?.removeTags("@param");
- childComment?.removeTags("@typeParam");
- childComment?.removeTags("@template");
- }
-
- // Since this reflection has signatures, we need to remove the comment from the non-primary
- // declaration location. For functions/methods/constructors, this means removing it from
- // the wrapping reflection. For type aliases, classes, and interfaces, this means removing
- // it from the contained signatures... if it's the same as what is on the signature.
- // This is important so that in type aliases we don't end up with a comment rendered twice.
- if (reflection.kindOf(ReflectionKind.SignatureContainer)) {
- delete reflection.comment;
- } else {
- reflection.comment?.removeTags("@param");
- reflection.comment?.removeTags("@typeParam");
- reflection.comment?.removeTags("@template");
+ if (signatureHadOwnComment) {
+ this.validateParamTags(
+ signature,
+ childComment,
+ signature.parameters || [],
+ signatureHadOwnComment,
+ );
- const parentComment = Comment.combineDisplayParts(
- reflection.comment?.summary,
- );
- for (const sig of signatures) {
- if (
- Comment.combineDisplayParts(sig.comment?.summary) ===
- parentComment
- ) {
- delete sig.comment;
- }
+ childComment.removeTags("@param");
+ childComment.removeTags("@typeParam");
+ childComment.removeTags("@template");
}
}
} |
…nterface Adding a failing test to reproduce #2521
That wasn't that bad at all, only like 3 hours to straighten out the remaining edge cases. One comment from the test case you added: /**
* Original comment.
*/
export interface Foo {
/** Overload 1 */
(): void;
/** Overload 2 */
(baz: number): void;
}
export const fooWithoutComment: Foo; In this case, /** {@inheritDoc Foo} */
export const fooWithoutComment: Foo; The signature comments are inherited because the only declaration of the signature is in the base class, so TypeDoc picks it up there. If they had declarations in the implementation, TypeDoc would look there for the comment, and wouldn't inherit one. |
Fixed with TypeDoc 0.26, which is releasing 2024/06/21 |
Search terms
const, variable, function, interface
This seems related to #1523.
Expected Behavior
Given the following
interface
and two exportedconst
(interpreted as functions because of their type declaration).I'd expect
fooWithoutComment
to copy the comment summary and signatures (including their comment summaries) fromFoo
.fooWithComment
to override the comment summary, with "New comment." but copy the signatures (including their comment summaries) fromFoo
.Actual Behavior
These are screenshots of the resulting documentation:
Notice how neither
fooWithoutComment
norfooWithComment
have comment summaries of their own and how all signatures offooWithComment
has all signature comments copied from the declaration instead of being copied from the comments ofFoo
's signatures.Steps to reproduce the bug
I found reproducing the bug using the "typedoc-repros" repo a bit too cumbersome, so I hope it's okay I made it a PR to the "typedoc" repo itself instead: #2522
Environment
The text was updated successfully, but these errors were encountered: