GitHub - samchon/ttsc: A `typescript-go` toolchain for compiler-powered plugins and type-safe execution + 20x faster TS lint integrated into compiler

3 min read Original article ↗

banner of ttsc

GitHub license NPM Version NPM Downloads Build Status Guide Documents Discord Badge

A typescript-go toolchain for compiler-powered transforms and type-safe execution.

  • ttsc: build, check, and transform.
  • ttsx: execute TypeScript with type checking.
    • 10x faster than ts-node.
    • type checking that tsx does not provide.
  • transformer support: compiler-powered libraries, such as typia.
    • @ttsc/lint: lint violations as TS compile errors.

Setup

Install the native TypeScript preview package with ttsc:

npm i -D ttsc @typescript/native-preview

Run TypeScript directly with ttsx (CLI command):

Build, check, or watch the project with ttsc:

npx ttsc
npx ttsc --noEmit
npx ttsc --watch

Prebuild or clear cached source-plugin binaries:

npx ttsc prepare
npx ttsc clean

Plugin Configuration

Add plugin entries under compilerOptions.plugins in your tsconfig.json.

{
  "compilerOptions": {
    "plugins": [
      {
        "transform": "@ttsc/lint",
        "config": {
          "no-var": "error",
          "no-explicit-any": "warning",
          "no-non-null-assertion": "off"
        }
      },
      { "transform": "@ttsc/paths" },
      { "transform": "typia/lib/transform" }
    ]
  }
}

The same configuration is used by both ttsc and ttsx commands.

# compile
npx ttsc

# execute
npx ttsx src/index.ts

This gives compiler-powered libraries one transform path for both build-time and runtime execution.

What Is a Transform?

A transform uses TypeScript types to generate JavaScript before runtime.

import typia, { tags } from "typia";
import { v4 } from "uuid";

const matched: boolean = typia.is<IMember>({
  id: v4(),
  email: "samchon.github@gmail.com",
  age: 30,
});
console.log(matched); // true

interface IMember {
  id: string & tags.Format<"uuid">;
  email: string & tags.Format<"email">;
  age: number &
    tags.Type<"uint32"> &
    tags.ExclusiveMinimum<19> &
    tags.Maximum<100>;
}

It is transformed into dedicated JavaScript:

import typia from "typia";
import * as __typia_transform__isFormatEmail from "typia/lib/internal/_isFormatEmail";
import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid";
import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32";
import { v4 } from "uuid";

const matched = (() => {
  const _io0 = (input) =>
    "string" === typeof input.id &&
    __typia_transform__isFormatUuid._isFormatUuid(input.id) &&
    "string" === typeof input.email &&
    __typia_transform__isFormatEmail._isFormatEmail(input.email) &&
    "number" === typeof input.age &&
    __typia_transform__isTypeUint32._isTypeUint32(input.age) &&
    19 < input.age &&
    input.age <= 100;
  return (input) => "object" === typeof input && null !== input && _io0(input);
})()({
  id: v4(),
  email: "samchon.github@gmail.com",
  age: 30,
});
console.log(matched); // true

ttsc applies this transform at build time; ttsx applies the same transform when running the file.

List of Plugins

ttsc ships a few small utility plugins in this repository.

  • @ttsc/banner: adds banner comments to emitted JS and declarations.
  • @ttsc/lint: type-check + lint in one compile pass, ~20x faster than eslint in theory.
  • @ttsc/paths: rewrites path aliases in emitted imports.
  • @ttsc/strip: removes configured calls and debugger statements.

Plugin authors should start from the Guide Documents.

Ecosystem plugins are listed below; PRs adding ttsc plugins are welcome.

  • @nestia/core: generates NestJS routes, OpenAPI, and SDKs.
  • typia: generates validators, serializers, and type-driven runtime code.

References