dsherret / ts-type-info

TypeScript AST and code generator [Deprecated]
MIT License
94 stars 8 forks source link
ast code-generation typescript

TSTypeInfo

npm version Build Status Coverage Status

TypeScript AST and code generator.

Uses the TypeScript Compiler API to get information about TypeScript code in an easy to use format.

npm install ts-type-info --save-dev

NOTICE - LIBRARY IS DEPRECATED

This library has been deprecated by ts-simple-ast:

https://github.com/dsherret/ts-simple-ast

Version 7.0 is the last final major release of ts-type-info.

There's certain issues with this library and to address them I had to do a complete redesign. ts-simple-ast wraps the typescript compiler rather than creating separate standalone objects. It's much more powerful and supports a lot more use cases.

AST

// V:\TestFile.ts

export class MyClass {
    myStringProperty: string;
    readonly myNumberProperty = 253;

    myMethod(myParameter: string) {
        return `Test: ${myParameter}`;
    }
}

Get the file info:

import * as TsTypeInfo from "ts-type-info";

const result = TsTypeInfo.getInfoFromFiles(["V:\\TestFile.ts"]);
const property = result.getFile("TestFile.ts")
    .getClass("MyClass")                            // get first by name
    .getProperty(p => p.defaultExpression != null); // or first by what matches

console.log(property.name);                   // myNumberProperty
console.log(property.type.text);              // number
console.log(property.defaultExpression.text); // 253
console.log(property.isReadonly);             // true

// or access the arrays directly
const myMethod = result.files[0].classes[0].methods[0];

console.log(myMethod.name); // myMethod

Code Generation

You can work with objects retrieved from the AST or start with your own new file definition:

import * as TsTypeInfo from "ts-type-info";

// create whatever you like at the start
const file = TsTypeInfo.createFile({
    classes: [{
        name: "MyClass",
        methods: [{
            name: "myMethod",
            parameters: [{ name: "myParam", type: "string" }],
            onBeforeWrite: writer => writer.write("// myMethod is here"),
            onWriteFunctionBody: writer => {
                writer.write(`if (myParam != null && myParam.length > 40)`).block(() => {
                    writer.write("alert(myParam)");
                });
                writer.newLine().write("return myParam;");
            }
        }]
    }]
});

// add to it later
const myClass = file.getClass("MyClass");
myClass.isAbstract = true;
myClass.addDecorator({
    name: "MyDecorator"
});

myClass.addProperty({
    name: "myProperty1",
    type: "string"
});
myClass.addProperty({
    name: "myProperty2",
    type: "number",
    defaultExpression: "4"
});

// write it out
console.log(file.write());

Outputs:

@MyDecorator
abstract class MyClass {
    myProperty1: string;
    myProperty2 = 4;

    // myMethod is here
    myMethod(myParam: string) {
        if (myParam != null && myParam.length > 40) {
            alert(myParam);
        }

        return myParam;
    }
}

Simple Examples

Full Examples

Include tsNodes

In case there's something you need from the compiler that's not implemented in this library, set the includeTsNodes option to true. This will include the TypeScript compiler nodes in the tsNode property of most objects.

import * as ts from "typescript";
import * as TsTypeInfo from "ts-type-info";

const result = TsTypeInfo.getInfoFromFiles(["V:\\TestFile.ts"], { includeTsNodes: true });
const typeChecker = result.getTypeChecker(); // ts.TypeChecker in case you need it
const myMethod = result.getFile("TestFile.ts").getClass("MyClass").getMethod("myMethod");
const myMethodNode = myMethod.tsNode as ts.MethodDeclaration;

console.log(myMethodNode.body.statements[0].getText()); // "return `Test: ${myParameter}`;"