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')
}
}