Skip to content

Commit d626468

Browse files
committed
Fix @link with declaration reference using !~
Resolves #2810
1 parent 9e667d0 commit d626468

File tree

4 files changed

+29
-1
lines changed

4 files changed

+29
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ title: Changelog
1515
- TypeDoc will now avoid making references to references, #2811.
1616
- Fixed output specific option specification, #2818.
1717
- Improved type reference conversion to avoid including defaulted type arguments, #2820.
18+
- Fixed parsing of declaration references which include a module and a local reference, #2810.
1819
- Improved link resolution logic to prioritize type alias properties with the
1920
same symbol over type literal properties within function parameters.
2021

site/declaration-references.md

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ The deliminator is used to determine how to navigate the project tree.
4848
| `#` | Indicates that the next component is a "member", including class instance properties, interface members, and enum members. |
4949
| `~` | Indicates that the next component is an export of a namespace/module. |
5050

51+
> [!warning] The TSDoc specification says that `~` traverses via locals. This is
52+
> different than TypeDoc's behavior. TypeDoc will treat `~` as a stricter `.`
53+
> which only supports navigating to a namespace/module export. It should
54+
> generally be avoided in favor of `.` for improved compatibility with VSCode.
55+
5156
```ts
5257
// module.ts
5358
/**

src/lib/converter/comments/declarationReference.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ export interface ComponentPath {
6565
* How to resolve the `path`
6666
* - `.` - Navigate via `exports` of symbol
6767
* - `#` - Navigate via `members` of symbol
68-
* - `~` - Navigate via `locals` of symbol
68+
* - `~` - Navigate via `locals` of symbol (note: TypeDoc does not support
69+
* locals, see the declaration reference docs)
6970
*/
7071
navigation: "." | "#" | "~";
7172
path: string;
@@ -432,6 +433,7 @@ export function parseDeclarationReference(
432433
let moduleSource: string | undefined;
433434
let symbolReference: SymbolReference | undefined;
434435
let resolutionStart: "global" | "local" = "local";
436+
let topLevelLocalReference = false;
435437

436438
const moduleSourceOrSymbolRef = parseModuleSource(source, pos, end);
437439
if (moduleSourceOrSymbolRef) {
@@ -443,6 +445,12 @@ export function parseDeclarationReference(
443445
pos = moduleSourceOrSymbolRef[1] + 1;
444446
resolutionStart = "global";
445447
moduleSource = moduleSourceOrSymbolRef[0];
448+
449+
// We might be referencing a local of a module
450+
if (source[pos] === "~") {
451+
topLevelLocalReference = true;
452+
pos++;
453+
}
446454
}
447455
} else if (source[pos] === "!") {
448456
pos++;
@@ -452,6 +460,9 @@ export function parseDeclarationReference(
452460
const ref = parseSymbolReference(source, pos, end);
453461
if (ref) {
454462
symbolReference = ref[0];
463+
if (topLevelLocalReference && symbolReference.path?.length) {
464+
symbolReference.path[0].navigation = "~";
465+
}
455466
pos = ref[1];
456467
}
457468

src/test/declarationReference.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,16 @@ describe("Declaration References", () => {
215215
equal(parse(""), undefined);
216216
equal(parse("@test/foo"), undefined);
217217
});
218+
219+
it("Handles module reference with top level ~ reference", () => {
220+
equal(parse("mod!~foo"), {
221+
moduleSource: "mod",
222+
resolutionStart: "global",
223+
symbolReference: {
224+
path: [{ navigation: "~", path: "foo" }],
225+
meaning: undefined,
226+
},
227+
});
228+
});
218229
});
219230
});

0 commit comments

Comments
 (0)