/ts-partial-type-resolver

Resolves types from TypeScript files without the need to compile a whole project.

Primary LanguageTypeScript

TypeScript Partial Type Resolver

Coverage Status

Under Construction 🏗

But feel free to look around!


This project has it's motiviation from creating mock data. I want to resolve types without compiling the whole project, and just load these types that I need. The goal is to resolve types like this:

type Person = {
	address: Address
	name: string
}

Into types like this:

type Person = {
	address: {
		street: string
		state: string
		city: string
		postalcode: number
	}
	name: string
}

Usage

Let's assume the following structure (You can also see the sources of that example here.

// state.ts
export enum State {
	ALABAMA = "AL",
	CALIFORNIA = "CA",
	NEVADA = "NV",
}

// language.ts
export enum Language {
	ENGLISH = "EN",
	GERMAN = "DE",
}

// address.ts
import { State } from "./state"

export type Address = {
	street: string
	state: State
	city: string
	postalcode: number
}

// person.ts
import { Language } from "./language"
import { Address } from "./address"

type Person = {
	name: string
	surname: string
	address: Address
	languages: Array<Language>
	employed: boolean
}

You can execute the parser like that:

import { Parser, prettify } from "ts-partial-type-parser"

const path = resolve(__dirname, "person.ts")
const parser = new Parser(path)
const person = parser.resolve("Person")

console.log(prettify(person.toString()))

that will log:

type Person = {
	name: string
	surname: string
	address: {
		street: string
		state: State
		city: string
		postalcode: number
	}
	languages: Array<Language>
	employed: boolean
}

it resolves the type. So you can also rewrite the type, with rewrite:

import { Parser, prettify, rewrite } from "ts-partial-type-parser"

const path = resolve(__dirname, "person.ts")
const parser = new Parser(path)
const person = parser.resolve("Person")

const rewrittenPerson = rewrite(person.type, {
	boolean(type) {
		return "faker.boolean()"
	},
	string(type) {
		return "faker.string()"
	},
	enum(type) {
		// take the first one
		return `${type.name}.${type.members.keys().next().value}`
	},
	number(type) {
		return "faker.number()"
	},
	reference(type) {
		return type.toString()
	},
})

console.log(`const mock = ${prettify(rewrittenPerson)}`)

this will output:

const mock = {
	name: faker.string(),
	surname: faker.string(),
	address: {
		street: faker.string(),
		state: State.ALABAMA,
		city: faker.string(),
		postalcode: faker.number(),
	},
	languages: [Language.ENGLISH],
	employed: faker.boolean(),
}

That way you can create mocking types or rewriting types!

Supported

  • - string
  • - number
  • - Date
  • - string & number literal
  • - objects (type literal)
  • - union types
  • - type reference inside the same file
  • - type reference from an import
  • - Array<TYPE>
  • - TYPE[] - Array
  • - Intersection
  • - Enums
  • - null
  • - Configuration to define types that should not be resolved

TODO

  • - resolving imports coming from libraries
  • - intersection merge on rewrite
  • - resolving alias imports
  • - pick
  • - omit
  • - boolean
  • - import * as type
  • - export * from
  • - interface
  • - extends
  • - void
  • - library imports
  • - undefined
  • - function
  • - ? optional properties
  • - [string, number]
  • - parenthesiszed types
  • - Looped types create a loop in the code