TypeScript Code Generator
A TypeScript code generator using Go text templates. This demonstrates how to add multi-language support to db-catalyst.
Overview
This package generates TypeScript interfaces from SQL schemas using:
- Go text templates for code generation
- Semantic type system for language-agnostic type mapping
- pg (node-postgres) as the target database library
Architecture
SQL Schema → Semantic Types → TypeScript Mapper → Templates → TypeScript Code
↓
INTEGER → CategoryBigInteger → number
TEXT → CategoryText → string
BOOLEAN → CategoryBoolean → boolean
Generated Code Example
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT,
created_at INTEGER NOT NULL
);
Output (TypeScript)
// Code generated by db-catalyst. DO NOT EDIT.
export interface Users {
id: number;
name: string;
email: string | null;
createdAt: number;
}
export type UsersId = number;
export type UsersRef = Users;
Type Mappings
| SQLite Type |
TypeScript Type |
Nullable |
| INTEGER |
number |
number | null |
| TEXT |
string |
string | null |
| BOOLEAN |
boolean |
boolean | null |
| REAL |
number |
number | null |
| BLOB |
Buffer |
Buffer | null |
| TIMESTAMP |
Date |
Date | null |
| UUID |
string |
string | null |
| JSON |
any |
any |
Usage
import "github.com/electwix/db-catalyst/internal/codegen/typescript"
// Create generator
gen, err := typescript.NewGenerator()
if err != nil {
log.Fatal(err)
}
// Generate from tables
files, err := gen.GenerateModels(tables)
if err != nil {
log.Fatal(err)
}
// Write files
for _, file := range files {
err := os.WriteFile(file.Path, file.Content, 0644)
if err != nil {
log.Fatal(err)
}
}
Templates
Templates are embedded using Go 1.16+ embed package:
templates/model.tmpl - Interface definitions
templates/queries.tmpl - Query functions
Template Functions
camelCase - Convert to camelCase
pascalCase - Convert to PascalCase
typescriptType - Convert semantic type to TypeScript type
Future Enhancements
- Query Generation: Generate pg query functions
- TypeORM Support: Generate TypeORM entities
- Prisma Support: Generate Prisma schema
- Zod Schemas: Generate runtime validation schemas
- Documentation: Generate TSDoc comments
Design Decisions
Why Templates?
- Pros:
- Easy to read/write TypeScript syntax directly
- Fast iteration
- Language-native formatting
- Cons:
- No compile-time safety
- Runtime errors possible
Why pg (node-postgres)?
- Most popular PostgreSQL library for Node.js
- Good TypeScript support
- Simple API
- Can be swapped for mysql2, better-sqlite3, etc.
Alternative Approaches
- String Builder: Simpler but harder to maintain
- TypeScript AST: Would need TS parser in Go (complex)
- External Tool: Call
prettier or similar (slower)
Comparison with Go Generator
| Aspect |
Go |
TypeScript |
| Method |
go/ast AST |
text/template |
| Type Safety |
Compile-time |
Runtime |
| Formatting |
goimports |
prettier (manual) |
| Complexity |
Higher |
Lower |
The Go AST approach is better for Go due to excellent tooling. Templates are better for other languages where we don't have Go-native AST libraries.
Testing
Run tests:
go test ./internal/codegen/typescript -v
The tests verify:
- Template loading and execution
- Type mappings (SQLite → TypeScript)
- Naming conventions (camelCase, PascalCase)
- File generation
- Module structure
Integration
To integrate with main db-catalyst:
- Add language selection to config
- Create LanguageGenerator interface
- Route to appropriate generator (Go/Rust/TypeScript)
- Generate all files for selected languages
See docs/language-agnostic-refactor.md for full architecture.
Notes on TypeScript Type System
- TypeScript has a simpler type system than Go or Rust
- All numbers are just
number (no int/float distinction)
- Null is explicit with union types (
string | null)
- Uses structural typing (not nominal)
- JSON is
any type
Differences from Rust Generator
| Aspect |
Rust |
TypeScript |
| Nullable |
Option<T> |
T | null |
| Integers |
i32, i64 |
number |
| Structs |
struct |
interface |
| Exports |
pub |
export |
| Arrays |
Vec<T> |
T[] |