Skip to content

Commit f97ec69

Browse files
committed
Improve docs for declaration references
1 parent 8472952 commit f97ec69

3 files changed

Lines changed: 85 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ title: Changelog
88

99
- Improved handling of comments for type aliases which have been declaration merged with functions, #3064.
1010
- Fixed anchor link generation to members named `$`, #3065.
11+
- Corrected typing of the `plugin` option to permit functions, #3066.
1112

1213
## v0.28.16 (2026-01-12)
1314

site/declaration-references.md

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ title: Declaration References
55
# Declaration References
66

77
> [!note] If [--useTsLinkResolution](options/comments.md#usetslinkresolution) is turned on (the default) this page
8-
> likely **does not apply** for your links within comments (though it will be used for
9-
> [external documents](./external-documents.md) and for the readme file). Declaration references are used only if that option is
10-
> off or TypeScript fails to resolve a link.
8+
> **may not apply** for your links within comments as TypeDoc will use TypeScript's resolution if TypeScript resolved
9+
> the link. This resolution strategy will only be used if TypeScript fails to parse the link or does not parse the
10+
> source document (e.g. for [external documents](./external-documents.md) and for the readme file).
1111
1212
Some tags like [`{@link}`](tags/link.md) and [`{@inheritDoc}`](tags/inheritDoc.md) can refer to other
1313
members of the documentation. These tags use declaration references to name another declaration.
@@ -17,6 +17,7 @@ the "new" [TSDoc](https://tsdoc.org/pages/spec/overview/) declaration references
1717
to make their resolution behavior more closely match the TypeScript language service (e.g. what VSCode does).
1818

1919
Declaration references are comprised of an optional module source, a component path, and an optional meaning.
20+
Once parsed, they are resolved according to the [resolution strategy](#resolution-strategy) described below.
2021

2122
## Module Source
2223

@@ -193,3 +194,79 @@ function foo(n: number): number;
193194
*/
194195
function foo(s: string): string;
195196
```
197+
198+
# Resolution Strategy
199+
200+
When resolving links TypeDoc resolves the module source, then the component path, and finally the meaning.
201+
202+
Link resolution is most easily understood with an example, the following project structure will be used in
203+
examples below:
204+
205+
```text
206+
project "My lib docs"
207+
module "@me/lib"
208+
class "Foo"
209+
static property "bar"
210+
property "bar"
211+
method "baz"
212+
signature 0 () => string
213+
signature 1 (x: number) => number
214+
215+
type alias "Bam"
216+
function "Bam"
217+
signature 0 () => string
218+
signature 1 (x: number) => number
219+
220+
namespace "Nested"
221+
variable "Bam"
222+
223+
module "@me/lib2"
224+
function "Bop"
225+
```
226+
227+
1. Resolve the Module Source:
228+
229+
TypeDoc first checks if a module is specified before `!`. If a module source is specified, then TypeDoc
230+
will get the root level reflection with the same name as the module. In the example above, `@me/lib!`
231+
and `@me/lib2!` will be resolved to the expected module, but `@me/fake!` will fail to resolve.
232+
233+
If the declaration reference does not specify a module source but starts with `!` then the link is treated
234+
as a globally specified link whose resolution starts at the project level. `!"@me/lib"` will also resolve
235+
to that module.
236+
237+
Otherwise, the link is treated as a local link which should start resolution at the comment location.
238+
TypeDoc will prioritize link resolution with fewer scope steps to the target, but will also check parents
239+
of a reflection for the link target. That is, `{@link Bam}` within the `Nested` namespace will resolve
240+
to `@me/lib.Nested.Bam`, but `{@link Bam}` in the `Foo` class's comment (or the property/method) will
241+
resolve to `@me/lib.Bam`.
242+
243+
2. Resolve the Component Path:
244+
245+
Component paths are resolved according to their delimiter. The first section of a component path
246+
is resolved as if the delimiter is `.`.
247+
248+
If the delimiter is `.`, TypeDoc will look for children of the current reflection, prioritizing
249+
exports and static attributes over member attributes. The link `{@link @my/lib!Foo.bar}` will link
250+
to the static property rather than the instance property, but `{@link my/lib!Foo.baz}` will successfully
251+
link to the method even though it isn't static.
252+
253+
If the delimiter is `#`, TypeDoc will look for class/interface instance members. The link
254+
`{@link @my/lib!Foo.bar}` will link to the instance property.
255+
256+
If the delimiter is `~`, TypeDoc will only look for children of the current reflection if the
257+
current reflection is a module. This delimiter isn't generally useful.
258+
259+
3. Resolve the Meaning:
260+
261+
Meanings are used to disambiguate links which could be intended to go to multiple locations.
262+
The keyword portion of the meaning is resolved first. `{@link @my/lib!Bam:type}` will link
263+
to the type alias, while `{@link @my/lib!Bam:function}` will link to the function.
264+
265+
Meanings may also include an index which further disambiguates the link. If you wanted to link
266+
to the second signature of the `Bam` function, `{@link @my/lib!Bam:function}` is insufficient
267+
and `{@link @my/lib!Bam:function(1)}` must be used instead.
268+
269+
An index may be included in a meaning without the keyword. This would be sufficient for linking
270+
to the first signature of the `baz` method: `{@link @my/lib!Foo.baz:0}`, but the `Bam` function
271+
is also merged with a type alias, so `{@link @my/lib!Bam:0}` could link to either the type alias
272+
or the first signature of the function.

src/lib/converter/comments/declarationReferenceResolver.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ export function resolveDeclarationReference(
3131
c.kindOf(ReflectionKind.SomeModule) &&
3232
c.name === ref.moduleSource,
3333
) || [];
34+
35+
if (!high.length && reflection.project.packageName === ref.moduleSource) {
36+
high.push(reflection.project);
37+
}
3438
} else if (ref.resolutionStart === "global") {
3539
high.push(reflection.project);
3640
if (reflection.project.children?.length === 1) {

0 commit comments

Comments
 (0)