I’m trying to generate function declarations from methods of an interface. Although the function are correctly created their JsDocs is missing, even when I explicitly say to the printer not to remove them.
Here is a simplify version of my interface:
//api-interface.ts
export interface SourceInterface {
/**
*
* The source of the data.
*
* @param label The label to be used as the source for the data.
*/
source: <T>(label: T) => void;
}
I’m expecting to generate the following file:
//api.ts
/**
*
* The source of the data.
*
* @param label The label to be used as the source for the data.
*/
export declare function source<T>(label: T): void;
Here is my code to generate the api.ts
file using the Typescript API (^5.3.3)
//generate-api.ts
import * as fs from 'node:fs';
import * as ts from 'typescript';
const interfaceFile = './api-interface.ts';
const sourceFile = ts.createSourceFile(
interfaceFile,
fs.readFileSync(interfaceFile, 'utf8'),
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TS
);
// Function to generate function declarations from interface
function generateFunctionDeclarations(node: ts.Node): ts.FunctionDeclaration[] {
if (!ts.isInterfaceDeclaration(node)) return [];
const functionDeclarations = node.members.map(member => {
if (ts.isPropertySignature(member) && member.type && ts.isFunctionTypeNode(member.type)) {
const functionName = (member.name as ts.Identifier).text;
const functionIdentifier = ts.factory.createIdentifier(functionName);
const typeParameters = member.type.typeParameters;
const parameters = member.type.parameters;
const returnType = member.type.type;
const jsDocTags = ts.getJSDocTags(member);
const modifiers = [
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)
];
const functionDeclaration = ts.factory.createFunctionDeclaration(
modifiers,
undefined,
functionIdentifier,
typeParameters,
parameters,
returnType,
undefined
);
if ('jsDoc' in functionDeclaration) functionDeclaration.jsDoc = jsDocTags;
return functionDeclaration;
}
return undefined;
}).filter(value => value !== undefined);
return functionDeclarations;
}
const functionDeclarations = sourceFile.statements.flatMap(generateFunctionDeclarations);
const apiFile = ts.createSourceFile('api.ts', '', ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
const result = ts.factory.updateSourceFile(apiFile, functionDeclarations);
const printer = ts.createPrinter({removeComments: false });
const resultText = printer.printFile(result);
fs.writeFileSync('api.ts', resultText);
Any idea what I’m missing?
Here is a TS Playground where I just read the interface code from a variable and print the result to console using the global ts
object, which is available in the Playground