Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A Golang struct to TypeScript class/interface converter

License

NotificationsYou must be signed in to change notification settings

tkrajina/typescriptify-golang-structs

Repository files navigation

Installation

The command-line tool:

go install github.com/tkrajina/typescriptify-golang-structs/tscriptify

The library:

go get github.com/tkrajina/typescriptify-golang-structs

Usage

Use the command line tool:

tscriptify -package=package/with/your/models -target=target_ts_file.ts Model1 Model2

If you need to import a custom type in Typescript, you can pass the import string:

tscriptify -package=package/with/your/models -target=target_ts_file.ts -import="import { Decimal } from 'decimal.js'" Model1 Model2

If all your structs are in one file, you can convert them with:

tscriptify -package=package/with/your/models -target=target_ts_file.ts path/to/file/with/structs.go

Or by using it from your code:

converter:=typescriptify.New().Add(Person{}).Add(Dummy{})err:=converter.ConvertToFile("ts/models.ts")iferr!=nil {panic(err.Error())}

Command line options:

$ tscriptify --helpUsage of tscriptify:-backup string        Directory where backup files are saved-package string        Path of the package with models-target string        Target typescript file

Models and conversion

If thePerson structs contain a reference to theAddress struct, then you don't have to addAddress explicitly. Only fields with a validjson tag will be converted to TypeScript models.

Example input structs:

typeAddressstruct {Citystring`json:"city"`Numberfloat64`json:"number"`Countrystring`json:"country,omitempty"`}typePersonalInfostruct {Hobbies []string`json:"hobby"`PetNamestring`json:"pet_name"`}typePersonstruct {Namestring`json:"name"`PersonalInfoPersonalInfo`json:"personal_info"`Nicknames    []string`json:"nicknames"`Addresses    []Address`json:"addresses"`Address*Address`json:"address"`Metadata     []byte`json:"metadata" ts_type:"{[key:string]:string}"`Friends      []*Person`json:"friends"`}

Generated TypeScript:

exportclassAddress{city:string;number:number;country?:string;constructor(source:any={}){if('string'===typeofsource)source=JSON.parse(source);this.city=source["city"];this.number=source["number"];this.country=source["country"];}}exportclassPersonalInfo{hobby:string[];pet_name:string;constructor(source:any={}){if('string'===typeofsource)source=JSON.parse(source);this.hobby=source["hobby"];this.pet_name=source["pet_name"];}}exportclassPerson{name:string;personal_info:PersonalInfo;nicknames:string[];addresses:Address[];address?:Address;metadata:{[key:string]:string};friends:Person[];constructor(source:any={}){if('string'===typeofsource)source=JSON.parse(source);this.name=source["name"];this.personal_info=this.convertValues(source["personal_info"],PersonalInfo);this.nicknames=source["nicknames"];this.addresses=this.convertValues(source["addresses"],Address);this.address=this.convertValues(source["address"],Address);this.metadata=source["metadata"];this.friends=this.convertValues(source["friends"],Person);}convertValues(a:any,classs:any,asMap:boolean=false):any{if(!a){returna;}if(a.slice){return(aasany[]).map(elem=>this.convertValues(elem,classs));}elseif("object"===typeofa){if(asMap){for(constkeyofObject.keys(a)){a[key]=newclasss(a[key]);}returna;}returnnewclasss(a);}returna;}}

If you prefer interfaces, the output is:

exportinterfaceAddress{city:string;number:number;country?:string;}exportinterfacePersonalInfo{hobby:string[];pet_name:string;}exportinterfacePerson{name:string;personal_info:PersonalInfo;nicknames:string[];addresses:Address[];address?:Address;metadata:{[key:string]:string};friends:Person[];}

In TypeScript you can just cast your json object in any of those models:

varperson=<Person>{"name":"Me myself","nicknames":["aaa","bbb"]};console.log(person.name);// The TypeScript compiler will throw an error for this lineconsole.log(person.something);

Custom Typescript code

Any custom code can be added to Typescript models:

classAddress{street :string;no :number;//[Address:]country:string;getStreetAndNumber(){returnstreet+" "+number;}//[end]}

The lines between//[Address:] and//[end] will be left intact afterConvertToFile().

If your custom code contain methods, then just casting yout object to the target class (with<Person> {...}) won't work because the casted object won't contain your methods.

In that case use the constructor:

varperson=newPerson({"name":"Me myself","nicknames":["aaa","bbb"]});

If you use golang JSON structs as responses from your API, you may want to have a common prefix for all the generated models:

converter:=typescriptify.New().converter.Prefix="API_"converter.Add(Person{})

The model name will beAPI_Person instead ofPerson.

Field comments

Field documentation comments can be added with thets_doc tag:

typePersonstruct {Namestring`json:"name" ts_doc:"This is a comment"`}

Generated typescript:

exportclassPerson{/** This is a comment */name:string;}

Custom types

If your field has a type not supported by typescriptify which can be JSONized as is, then you can use thets_type tag to specify the typescript type to use:

typeDatastruct {Countersmap[string]int`json:"counters" ts_type:"CustomType"`}

...will create:

exportclassData{counters:CustomType;}

If the JSON field needs some special handling before converting it to a javascript object, usets_transform.For example:

typeDatastruct {Time time.Time`json:"time" ts_type:"Date" ts_transform:"new Date(__VALUE__)"`}

Generated typescript:

exportclassDate{time:Date;constructor(source:any={}){if('string'===typeofsource)source=JSON.parse(source);this.time=newDate(source["time"]);}}

In this case, you should always usenew Data(json) instead of just casting<Data>json.

If you use a custom type that has to be imported, you can do the following:

converter:=typescriptify.New()converter.AddImport("import Decimal from 'decimal.js'")

This will put your import on top of the generated file.

Global custom types

Additionally, you can tell the library to automatically use a given Typescript type and custom transformation for a type:

converter:=New()converter.ManageType(time.Time{},TypeOptions{TSType:"Date",TSTransform:"new Date(__VALUE__)"})

If you only want to changets_transform but notts_type, you can pass an empty string.

Enums

There are two ways to create enums.

Enums with TSName()

In this case you must provide a list of enum values and the enum type must have aTSName() string method

typeWeekdayintconst (SundayWeekday=iotaMondayTuesdayWednesdayThursdayFridaySaturday)varAllWeekdays= []Weekday{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday, }func (wWeekday)TSName()string {switchw {caseSunday:return"SUNDAY"caseMonday:return"MONDAY"caseTuesday:return"TUESDAY"caseWednesday:return"WEDNESDAY"caseThursday:return"THURSDAY"caseFriday:return"FRIDAY"caseSaturday:return"SATURDAY"default:return"???"}}

If this is too verbose for you, you can also provide a list of enums and enum names:

varAllWeekdays= []struct {ValueWeekdayTSNamestring}{{Sunday,"SUNDAY"},{Monday,"MONDAY"},{Tuesday,"TUESDAY"},{Wednesday,"WEDNESDAY"},{Thursday,"THURSDAY"},{Friday,"FRIDAY"},{Saturday,"SATURDAY"},}

Then, when converting modelsAddEnum() to specify the enum:

converter:=New().AddEnum(AllWeekdays)

The resulting code will be:

exportenumWeekday{SUNDAY=0,MONDAY=1,TUESDAY=2,WEDNESDAY=3,THURSDAY=4,FRIDAY=5,SATURDAY=6,}exportclassHolliday{name:string;weekday:Weekday;}

License

This library is licensed under theApache License, Version 2.0

About

A Golang struct to TypeScript class/interface converter

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors12


[8]ページ先頭

©2009-2025 Movatter.jp