I want to create type files like this programatically:
export type Car = {
color: string;
// ... tons of properties
};
Thats seems pretty easy using ts-morph
addTypeAlias method:
sourceFile.addTypeAlias({
name: 'Car',
type: theType,
isExported: true,
});
Though unfortunately theType
here must be string | WriterFunction
.
And I want it to be a TypeLiteral! Is there a way to this with ts-morph
that I am missing? Ofcourse I could construct my type literal as a string by some looping and string concatenation etc, but I would really like to avoid building my files that way - then I might as well use template/stub files and fs.
Any other way to do this in a more programmatic/Node-class based approach?
Let's consider the following Node.js version as the current version:
$ node --version
v18.13.0
Let's consider the following npm version as the current version:
$ npm --version
9.2.0
Let's consider the following versions of the dependencies as the current versions (an excerpt from the package.json
file):
{
<…>,
"dependencies": {
"ts-morph": "17.0.1",
"typescript": "4.9.5"
},
"devDependencies": {
"ts-node": "10.9.1"
}
}
Though unfortunately
theType
here must bestring | WriterFunction
. And I want it to be a TypeLiteral! Is there a way to this withts-morph
that I am missing?
Currently, it seems there is no straightforward solution.
Please, see the following seemingly related GitHub issues:
Any other way to do this in a more programmatic/Node-class based approach?
Let's consider some possible solutions.
ts-morph
: Use object type writer (Writers.objectType()
static method)It may be considered as more programmatic, but it is still a writer-based (not a node-based) approach.
References:
Writers.objectType()
static method. ts-morph/Writers.ts at 17.0.1 · dsherret/ts-morph.src/index-ts-morph.ts
fileimport { Project, WriterFunction, Writers } from "ts-morph";
async function createFile(outputFilePath: string) {
const project = new Project();
const sourceFile = project.createSourceFile(
outputFilePath,
undefined,
{ overwrite: true }
);
const typeAliasDeclarations = [
createExportedTypeAliasDeclaration("Book"),
createExportedTypeAliasDeclaration("House"),
createExportedTypeAliasDeclaration("Car"),
];
sourceFile.addTypeAliases(typeAliasDeclarations);
await sourceFile.save();
};
function createExportedTypeAliasDeclaration(name: string) {
const writerFunction: WriterFunction = Writers.objectType({
properties: [
{
name: "color",
type: "string"
}
]
});
return ({
name: name,
type: writerFunction,
isExported: true,
});
}
await createFile("output.ts");
$ npx ts-node src/index-ts-morph.ts
$ cat output.ts
export type Book = {
color: string;
};
export type House = {
color: string;
};
export type Car = {
color: string;
};
Please, note the strange indentation.
Probably, it is caused by a ts-morph
defect?
typescript
: Use typescript
instead of ts-morph
References:
src/index-typescript.ts
fileimport { writeFile } from "fs/promises";
import ts from "typescript";
const { factory } = ts;
async function createFile(outputFilePath: string) {
const typeAliasDeclarations = [
createExportedTypeAliasDeclaration("Book"),
createExportedTypeAliasDeclaration("House"),
createExportedTypeAliasDeclaration("Car"),
];
const printer = ts.createPrinter({
newLine: ts.NewLineKind.LineFeed
});
const nodes = factory.createNodeArray(typeAliasDeclarations);
const sourceFile = ts.createSourceFile(
"this-name-is-ignored.ts",
"",
ts.ScriptTarget.Latest,
false,
ts.ScriptKind.TS
);
const printedString = printer.printList(
ts.ListFormat.MultiLine,
nodes,
sourceFile
);
await writeFile(outputFilePath, printedString);
};
function createExportedTypeAliasDeclaration(name: string) {
const colorPropertySignature = factory.createPropertySignature(
undefined,
factory.createIdentifier("color"),
undefined,
factory.createTypeReferenceNode(
factory.createIdentifier("string"),
undefined
)
);
return factory.createTypeAliasDeclaration(
[
factory.createToken(ts.SyntaxKind.ExportKeyword)
],
factory.createIdentifier(name),
undefined,
factory.createTypeLiteralNode([
colorPropertySignature
])
);
}
await createFile("output.ts");
$ npx ts-node src/index-typescript.ts
$ cat output.ts
export type Book = {
color: string;
};
export type House = {
color: string;
};
export type Car = {
color: string;
};