Converts TypeScript types to Go structs using the TypeScript Compiler API.
npx tsx src/index.ts examples/models.ts > models.goKeeping TypeScript interfaces and Go structs in sync is fine until someone adds a field and forgets to update the other side. This generates your Go types from TypeScript so that can't happen. Built on the TypeScript Compiler API, so it resolves types the way the compiler does, and not by reading text.
| TypeScript | Go |
|---|---|
string |
string |
number |
float64 |
boolean |
bool |
string | null |
*string |
string[] / Array<T> |
[]T |
Record<K, V> |
map[K]V |
Date |
time.Time |
Optional fields ? |
pointer + omitempty |
| String enums | typed string constants |
| Numeric enums | typed int constants |
| Double/Float enums | typed float64 constants |
Input:
interface User {
id: string;
age: number;
email: string | null;
roles: string[];
address?: Address;
createdAt: Date;
}
interface Address {
street: string;
city: string;
}
enum Status {
Active = "active",
Inactive = "inactive",
}Output:
package models
import "time"
type Status string
const (
StatusActive Status = "active"
StatusInactive Status = "inactive"
)
type User struct {
Id string `json:"id"`
Age float64 `json:"age"`
Email *string `json:"email"`
Roles []string `json:"roles"`
Address *Address `json:"address,omitempty"`
CreatedAt time.Time `json:"createdAt"`
}
type Address struct {
Street string `json:"street"`
City string `json:"city"`
}git clone https://github.com/your-username/ts-to-go
cd ts-to-go
pnpm installnpx tsx src/index.ts path/to/models.ts > models.goMultiple files:
npx tsx src/index.ts src/types/*.ts > models.goThe TypeScript Compiler API gives you a full program object - type checker included. From there:
parser.ts- creates ats.Programfrom your filesextractor.ts- walks the AST withts.forEachChild, finds interface/type/enum declarationsmapper.ts- converts eachts.TypeNodeto a Go type string using the type checker for accurate symbol resolutionemitter.ts- renders the collected types as Go source
-
Union types beyond
T | null/T | undefinedbecomeinterface{} -
Function signatures in interfaces are skipped
-
Mapped types and conditional types are not supported
MIT