@vlr/type-parser

basic typescript files parser, produces type information in convenient form

Usage no npm install needed!

<script type="module">
  import vlrTypeParser from 'https://cdn.skypack.dev/@vlr/type-parser';
</script>

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:

  1. types
  2. constants
  3. enums
  4. interfaces
  5. classes
  6. 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);
  }
}