README
@vlr/type-parser
Library is made to be used for code generation. Before this, every generator I made, had its own parser, parsing its own things, intersecting on some of the functionality. From now on, parser is extracted into its own library and every new generator will be using it.
Usage
Easiest way to use this is from gulp task, with @vlr/gulp-transform module
import { transform } from "@vlr/gulp-transform";
import { parseTypes } from "@vlr/type-parser";
gulp.src(files)
.pipe(transform(file => generateSomething(parseTypes(file)); )
.pipe(gulp.dest())
This way, generator input parameter should be of TypesModel type.
If the file is read with another tool, to parse the file, method parseTypes should be provided with object containing file contents, file name and folder.
Types Model
Model will contain the following parsed entities:
- types
- constants
- enums
- interfaces
- classes
- functions
All types should be in the root of the file to be parsed. I.e. types inside any sort of brackets will not be included. Also, Types not prefixed with export keyword will not be included.
Type id
Each parsed entity contains definition, or id.
Definition has name and folder/file where type is defined
Types
Parsed type contains only type id.
Type should look like this to be properly parsed:
export type MyType = string;
Constants
Same as types, constant contains only type id.
const a: number = 2;
Enums
Parsed enum contains a list of value names. Values ("b" and 5) are not included.
Enum should look like this to be properly parsed:
export enum MyEnum {
a,
b = "b",
c = 5
}
Functions
Function contains list of parameters and return type.
Parameter contains parameter name, type name and definitions of imported types included in type name in case of a composed type.
For example, parameter a: MyType<string, MySecondType> has 2 definitions, for MyType and for MySecondType. If those 2 are defined in the same file, their definitions will have the same file and folder as currently parsed file. If type is imported, then imports will be used to calculate absolute path where this imported type is defined.
Function should look like this to be parsed:
export function a(b: string, c: MyType<string>): MyOtherType<MyThirdType> {
console.log("hello world");
return null;
}
Interfaces
Interface contains list of defined fields and functions.
Field contains field name, field type name and definitions of imported types included in type name.
Functions are the same as separately defined functions.
Also interface will contain a list of other types it extends, if any.
Interface should be defined following way to be parsed:
import { MyOtherType } from "../myOther.type";
export interface MyType extends MySecondType {
// simple field
a: string;
// field with composed imported type
b: MyOtherType<string>
// function
c: (f1: string) => number;
}
Classes
Class, same as interface, contains a list of fields, functions, and types it extends. In addition class has interfaces it implements and a constructor. Fields and functions of the class should be explicitly defined as public to be included. Also, if constructor fields are defined public, they will be included as fields.
Class should be defined like this to be parsed:
export class MyClass implements MyInterface {
public b: number;
constructor(public a: string) {
}
public c(a: string): void {
console.log(a);
}
}