• Stars
    star
    508
  • Rank 86,941 (Top 2 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 9 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Golang struct to TypeScript class/interface converter

A Golang JSON to TypeScript model converter

Installation

The command-line tool:

go get 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")
if err != nil {
    panic(err.Error())
}

Command line options:

$ tscriptify --help
Usage 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 the Person structs contain a reference to the Address struct, then you don't have to add Address explicitly. Only fields with a valid json tag will be converted to TypeScript models.

Example input structs:

type Address struct {
	City    string  `json:"city"`
	Number  float64 `json:"number"`
	Country string  `json:"country,omitempty"`
}

type PersonalInfo struct {
	Hobbies []string `json:"hobby"`
	PetName string   `json:"pet_name"`
}

type Person struct {
	Name         string       `json:"name"`
	PersonalInfo PersonalInfo `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:

export class Address {
    city: string;
    number: number;
    country?: string;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.city = source["city"];
        this.number = source["number"];
        this.country = source["country"];
    }
}
export class PersonalInfo {
    hobby: string[];
    pet_name: string;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.hobby = source["hobby"];
        this.pet_name = source["pet_name"];
    }
}
export class Person {
    name: string;
    personal_info: PersonalInfo;
    nicknames: string[];
    addresses: Address[];
    address?: Address;
    metadata: {[key:string]:string};
    friends: Person[];

    constructor(source: any = {}) {
        if ('string' === typeof source) 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) {
			return a;
		}
		if (a.slice) {
			return (a as any[]).map(elem => this.convertValues(elem, classs));
		} else if ("object" === typeof a) {
			if (asMap) {
				for (const key of Object.keys(a)) {
					a[key] = new classs(a[key]);
				}
				return a;
			}
			return new classs(a);
		}
		return a;
	}
}

If you prefer interfaces, the output is:

export interface Address {
    city: string;
    number: number;
    country?: string;
}
export interface PersonalInfo {
    hobby: string[];
    pet_name: string;
}
export interface Person {
    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:

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

Custom Typescript code

Any custom code can be added to Typescript models:

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

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

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:

var person = new Person({"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 be API_Person instead of Person.

Field comments

Field documentation comments can be added with the ts_doc tag:

type Person struct {
	Name string `json:"name" ts_doc:"This is a comment"`
}

Generated typescript:

export class Person {
	/** 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 the ts_type tag to specify the typescript type to use:

type Data struct {
    Counters map[string]int `json:"counters" ts_type:"CustomType"`
}

...will create:

export class Data {
        counters: CustomType;
}

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

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

Generated typescript:

export class Date {
	time: Date;

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

In this case, you should always use new 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 change ts_transform but not ts_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 a TSName() string method

type Weekday int

const (
	Sunday Weekday = iota
	Monday
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
)

var AllWeekdays = []Weekday{ Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, }

func (w Weekday) TSName() string {
	switch w {
	case Sunday:
		return "SUNDAY"
	case Monday:
		return "MONDAY"
	case Tuesday:
		return "TUESDAY"
	case Wednesday:
		return "WEDNESDAY"
	case Thursday:
		return "THURSDAY"
	case Friday:
		return "FRIDAY"
	case Saturday:
		return "SATURDAY"
	default:
		return "???"
	}
}

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

var AllWeekdays = []struct {
	Value  Weekday
	TSName string
}{
	{Sunday, "SUNDAY"},
	{Monday, "MONDAY"},
	{Tuesday, "TUESDAY"},
	{Wednesday, "WEDNESDAY"},
	{Thursday, "THURSDAY"},
	{Friday, "FRIDAY"},
	{Saturday, "SATURDAY"},
}

Then, when converting models AddEnum() to specify the enum:

    converter := New().
        AddEnum(AllWeekdays)

The resulting code will be:

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

License

This library is licensed under the Apache License, Version 2.0

More Repositories

1

gpxpy

gpx-py is a python GPX parser. GPX (GPS eXchange Format) is an XML based file format for GPS tracks.
Python
1,015
star
2

srtm.py

Geo elevation data parser for "The Shuttle Radar Topography Mission" data
Python
245
star
3

git-plus

Git utilities
Python
196
star
4

10000sentences

10,000 sentences: an Android app to help you learn new words in foreign languages
Java
162
star
5

go-reflector

Go reflection simplified
Go
99
star
6

gpxgo

GPX library for golang
Go
93
star
7

uvod-u-git

Git introduction: A book about git (in Croatian). Uvod u git: Sve što ste ikad htjeli znati o gitu, a niste se usudili pitati.
TeX
86
star
8

leaflet-editable-polyline

editable polylines plugin for leaflet
JavaScript
76
star
9

ftmpl

Fast typesafe templating for golang
Go
62
star
10

gpx-cmd-tools

Commandline tools for GPX
Python
49
star
11

golongfuncs

Find long/complex Golang functions in your code
Go
29
star
12

android-hls-playground

Introduction to HTTP Live Streaming: Example code
Java
21
star
13

cartesius

Simple python library for drawing coordinate system images and graphs
Python
21
star
14

go-elevations

SRTM parser for golang
Go
20
star
15

multi-git

git plugin that enables you to execute a single git command on multiple repositories
Python
13
star
16

gpxchart

A command-line tool and library for elevation charts from GPX files.
Go
12
star
17

geoelevations

SRTM (world elevations) and EGM (world undulations) parser library for Ruby
Ruby
10
star
18

echo-http-requests

GoogleAppEngine app that can be used to test http requests expected on a predefined url when you don't have a publicly available IP address. It is available on http://echo-http-requests.appspot.com
Python
7
star
19

Trackprofiler

TrackProfiler is a small free utility for exporting GPS track profiles into PNG images.
Java
4
star
20

Save-layers-as-images-in-GIMP

GIMP plugin to save layers as images in GIMP
Python
4
star
21

TinyLayerAroundGit

Just an experiment -- simple git plugin for eclipse
Java
4
star
22

slo-dictionary-importer

Go
3
star
23

gaeutils

Utility for GoogleAppEngine
Python
3
star
24

yactest

(Yet another) Minimalistic C unit testing "microframework".
C
3
star
25

cmd-tools

My personal utility command line tools
Python
2
star
26

tkrajina.github.com

My home
HTML
2
star
27

Salabahteri

Matematičke formule
TeX
2
star
28

TileStitcher

OSM tile stitcher
Python
2
star
29

anki-tts

Add TTS (text-to-speech) audio attachment to your Anki decks
Go
2
star
30

simple-py-nn

Hopfield neural network in python. This is a plain rewrite of the algorithm in Mark Thompson book JavaAI (http://www.markwatson.com/opencontent/). Just for testing purposes.
Python
2
star
31

panoye-f

Panoye PHP framework
PHP
1
star
32

GraphAnything

Java
1
star
33

yapd

Yet Another (Simple) PHP Debugger - YAPD
PHP
1
star
34

potres-app-mobile

TypeScript
1
star
35

pdf-tools

A few small helpers for pdf documents
Go
1
star
36

PhoneGapPlayground_Assets

Playing with PhoneGap
JavaScript
1
star
37

java-gps-calorie-calculator

Java calorie calculator for GPS data
Java
1
star
38

haskell-playground

Playing with haskell
Haskell
1
star
39

slo-dictionary-app

Slovene Thesaurus and Collocations dictionary app
TypeScript
1
star
40

jutils.js

Utility javascript library
JavaScript
1
star
41

PhoneGapPlayground_Android

Playin with PhoneGap
JavaScript
1
star
42

dotfiles

Vim Script
1
star
43

sgf2img

HTML
1
star
44

run_or_raise

Find and raise an XWindows program, run it otherwise.
C
1
star
45

version-control-graphs-in-latex

Code version control graphs in LaTeX graphics
Python
1
star
46

sgf-ts

SGF parser and goban library for typescript
TypeScript
1
star