Вот мой код:
const filename = 'example.ts';
const code = `
/**
* @description foobar
*
* @see test
*/
class Foo {};
`;
const sourceFile = ts.createSourceFile(filename, code, ts.ScriptTarget.ESNext);
const visitNode = (node: ts.Node) => {
ts.forEachChild(node, visitNode);
console.info(ts.SyntaxKind[node.kind], node);
console.info('--', ts.getJSDocTags(node));
console.info(
ts.forEachLeadingCommentRange(
sourceFile.text,
node.getFullStart(),
(pos, end, kind) => {
console.info(sourceFile.text.slice(pos, end));
}
)
);
};
ts.forEachChild(sourceFile, visitNode);
Я не могу понять, почему все призывы ts.getJSDocTags
вернуть товар.
Вот репродукция stackblitz.
Проблемы, связанные с JSDocTag: github.com/microsoft/TypeScript/…
@ArtBindu Я считаю, что это не связанная с этим проблема.
Есть это и пример здесь с использованием API из интерфейса symbol
.
Я отладил ваш пример кода (репродукция stackblitz.) и обнаружил проблему, почему он возвращает empty array
в результате ts.getJSDocTags(node)
.
Пожалуйста, проверьте библиотеку машинописных текстов: node_modules/typescript/lib/tsc.js
.
Есть проблема.
Сначала проверьте функцию getJSDocTags
, там мы вызываем getJSDocTagsWorker
функцию со значением noCache
параметров как false
.
function getJSDocTags(node) {
return getJSDocTagsWorker(
node,
/*noCache*/
false
);
}
Затем проверьте функцию getJSDocTagsWorker
.
function getJSDocTagsWorker(node, noCache) {
var _a;
if (!canHaveJSDoc(node))
return emptyArray;
let tags = (_a = node.jsDoc) == null ? void 0 : _a.jsDocCache;
if (tags === void 0 || noCache) {
... ... ...
}
return tags;
}
Здесь значение tags
равно empty array ([])
. Потому что, _a.jsDocCache = node.jsDoc.jsDocCache = []
.
Кроме того, значение noCache
равно false
Таким образом, он не входит во второй блок if (tags === void 0 || noCache
) и не возвращает значение tags
как empty array
.
Прикрепил скрин для справки.
Я надеюсь, что это поможет вам.
Вот пример на stackblitz.
Вам необходимо создать программу, а затем использовать средство проверки типов, чтобы получить связанный символ из узла AST. Затем из интерфейса symbol
вы можете сослаться на работающую getJSDocTags
реализацию.
Учитывая этот файл.ts:
/**
*
* @deprecated
* test
*
* @description foobar
*
* @see test
* @param a some comment
*/
class Foo {}
Вы можете создать документацию для тегов JSDoc следующим образом:
(Скажем, это файл main.ts)
import ts from 'typescript';
const generateDocumentation = (
fileNames: string[],
options: ts.CompilerOptions
): void => {
const program = ts.createProgram(fileNames, options);
const checker = program.getTypeChecker();
const visit = (node: ts.Node) => {
if (ts.isClassDeclaration(node) && node.name) {
const symbol = checker.getSymbolAtLocation(node.name);
if (symbol) {
const jsDocTags = symbol.getJsDocTags();
jsDocTags.forEach((tag) => {
console.info('--name--', tag.name);
console.info('--text--', tag.text);
});
}
}
};
for (const sourceFile of program.getSourceFiles()) {
if (!sourceFile.isDeclarationFile) {
// Walk the tree to search for classes
ts.forEachChild(sourceFile, visit);
}
}
};
generateDocumentation(['file.ts'], {
target: ts.ScriptTarget.ESNext,
});
Вы можете проверить это, выполнив следующие шаги:
tsc main.ts -m nodenext
node main.js
Или просто используйте tsx
и npm run dev
.
Решение на самом деле довольно простое. ts.createSourceFile
необходимо, чтобы 4-й аргумент setParentNodes?: boolean | undefined
был true
.
ts.createSourceFile(filename, code, ts.ScriptTarget.ESNext, true);
Это действительная проблема в Typescript. github.com/microsoft/TypeScript/issues/42895