Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

TypeScript Cookbook

Practical, copy-paste-ready recipes for TypeScript code generation. For the full API of each spec type, see Building Functions & Fields, Building Types & Enums, and Files & Projects.

Class with imports

use sigil_stitch::prelude::*;

let user_type = TypeName::importable_type("./models", "User");
let repo_type = TypeName::importable("./repository", "UserRepository");

let body = CodeBlock::of("return this.repo.findById(id)", ()).unwrap();

let type_spec = TypeSpec::builder("UserService", TypeKind::Class)
    .visibility(Visibility::Public)
    .add_field(
        FieldSpec::builder("repo", repo_type.clone())
            .visibility(Visibility::Private)
            .is_readonly()
            .build()
            .unwrap(),
    )
    .add_method(
        FunSpec::builder("getUser")
            .is_async()
            .add_param(ParameterSpec::new("id", TypeName::primitive("string")).unwrap())
            .returns(TypeName::generic(TypeName::primitive("Promise"), vec![user_type]))
            .body(body)
            .build()
            .unwrap(),
    )
    .build()
    .unwrap();

let output = FileSpec::builder("user_service.ts")
    .add_type(type_spec)
    .build()
    .unwrap()
    .render(80)
    .unwrap();
import type { User } from './models'
import { UserRepository } from './repository'

export class UserService {
    private readonly repo: UserRepository;

    async getUser(id: string): Promise<User> {
        return this.repo.findById(id)
    }
}

Interface with generics

use sigil_stitch::prelude::*;

let type_spec = TypeSpec::builder("Repository", TypeKind::Interface)
    .visibility(Visibility::Public)
    .add_type_param(TypeParamSpec::new("T"))
    .add_method(
        FunSpec::builder("findById")
            .add_param(ParameterSpec::new("id", TypeName::primitive("string")).unwrap())
            .returns(TypeName::generic(TypeName::primitive("Promise"), vec![TypeName::primitive("T")]))
            .build()
            .unwrap(),
    )
    .add_method(
        FunSpec::builder("save")
            .add_param(ParameterSpec::new("entity", TypeName::primitive("T")).unwrap())
            .returns(TypeName::generic(TypeName::primitive("Promise"), vec![TypeName::primitive("void")]))
            .build()
            .unwrap(),
    )
    .build()
    .unwrap();
export interface Repository<T> {
    findById(id: string): Promise<T>;
    save(entity: T): Promise<void>;
}

Type alias

use sigil_stitch::prelude::*;

let type_spec = TypeSpec::builder("UserId", TypeKind::TypeAlias)
    .visibility(Visibility::Public)
    .extends(TypeName::primitive("string"))
    .build()
    .unwrap();
export type UserId = string;

Enum

use sigil_stitch::prelude::*;

let type_spec = TypeSpec::builder("Direction", TypeKind::Enum)
    .visibility(Visibility::Public)
    .add_variant(
        EnumVariantSpec::builder("Up")
            .value(CodeBlock::of("'UP'", ()).unwrap())
            .build()
            .unwrap(),
    )
    .add_variant(
        EnumVariantSpec::builder("Down")
            .value(CodeBlock::of("'DOWN'", ()).unwrap())
            .build()
            .unwrap(),
    )
    .add_variant(
        EnumVariantSpec::builder("Left")
            .value(CodeBlock::of("'LEFT'", ()).unwrap())
            .build()
            .unwrap(),
    )
    .add_variant(
        EnumVariantSpec::builder("Right")
            .value(CodeBlock::of("'RIGHT'", ()).unwrap())
            .build()
            .unwrap(),
    )
    .build()
    .unwrap();
export enum Direction {
  Up = 'UP',
  Down = 'DOWN',
  Left = 'LEFT',
  Right = 'RIGHT',
}

Abstract class

use sigil_stitch::prelude::*;

let body = CodeBlock::of("console.log('handled')", ()).unwrap();

let type_spec = TypeSpec::builder("BaseController", TypeKind::Class)
    .visibility(Visibility::Public)
    .is_abstract()
    .add_method(
        FunSpec::builder("handleRequest")
            .is_abstract()
            .add_param(ParameterSpec::new("req", TypeName::primitive("Request")).unwrap())
            .returns(TypeName::primitive("Response"))
            .build()
            .unwrap(),
    )
    .add_method(
        FunSpec::builder("log")
            .visibility(Visibility::Protected)
            .body(body)
            .build()
            .unwrap(),
    )
    .build()
    .unwrap();
export abstract class BaseController {
  abstract handleRequest(req: Request): Response;

  protected log() {
    console.log('handled')
  }
}