Skip to content

ying-jeanne/cuetsy

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cuetsy Logo

Installation · Usage

cuetsy

Converting CUE objects to their TypeScript equivalent (highly experimental!)

  • CUE makes defining and validating canonical data specification easy
  • TypeScript is dominant in the frontend, but cannot natively benefit from this
  • CUE types have direct TypeScript equivalents, so cuetsy can bridge this gap

Example

CUETypeScript
DiceFaces: 1 | 2 | 3 | 4 | 5 | 6 @cuetsy(targetType="type")

Animal: {
    Name: string
    Sound: string
} @cuetsy(targetType="interface")

LeggedAnimal: Animal & {
    Legs: int
} @cuetsy(targetType="interface")

Pets: "Cat" | "Dog" | "Horse" @cuetsy(targetType="enum")
export type DiceFaces = 1 | 2 | 3 | 4 | 5 | 6;
export interface Animal {
  Name: string;
  Sound: string;
}
export interface LeggedAnimal extends Animal {
  Legs: number;
}
export enum Pets {
  Cat = "Cat",
  Dog = "Dog",
  Horse = "Horse",
}

Status

Cuetsy is in its early development, so it does not support all TypeScript features. However, the following are supported:

Installation

Cuetsy can be installed using Go 1.16+

$ go install github.com/sdboyer/cuetsy/cmd/cuetsy

Usage

cuetsy must be invoked on files as follows:

$ cuetsy [file.cue]

This will create a logically equivalent [file].ts

Union Types

CUE TypeScript @cuetsy(targetType)
Disjunction Union Type type

Union types are expressed in CUE and TypeScript nearly the same way, namely a series of disjunctions (a | b | c):

CUETypeScript
MyUnion: 1 | 2 | 3 | 4 | 5 | 6 @cuetsy(targetType="type")
export type MyUnion = 1 | 2 | 3 | 4 | 5 | 6;

Interfaces

CUE TypeScript @cuetsy(targetType)
Struct Interface interface

TypeScript interfaces are expressed as regular structs in CUE.

Caveats:

  • Nested structs are not supported
CUETypeScript
MyInterface: {
    Num: number
    Text: string
    List: [...number]
    Truth: bool
} @cuetsy(targetType="interface")
export interface MyInterface {
  List: number[];
  Num: number;
  Text: string;
  Truth: boolean;
}

Inheritance

Interfaces can optionally inherit from another interface. This is expressed using the union operator &:

CUETypeScript
AInterface: {
    AField: string
} @cuetsy(targetType="interface")

BInterface: AInterface & {
    BField: int
} @cuetsy(targetType="interface")
export interface AInterface {
  AField: string;
}
export interface BInterface extends AInterface {
  BField: number;
}

Enums

CUE TypeScript @cuetsy(targetType)
Disjunction, Struct Enum enum

Cuetsy supports two ways of expressing TypeScript enums in CUE:

Disjunction style

Disjunctions may be used in a very similar way to Union Types. The keys of the enum are automatically inferred as the titled camel-case variant of their value:

CUETypeScript
MyEnum: "foo" | "bar" | "baz" @cuetsy(targetType="enum")
export enum MyEnum {
  Bar = "bar",
  Baz = "baz",
  Foo = "foo",
}

Struct style

If the implicit keys are insufficient, the struct based style gives more control:

CUETypeScript
MyEnum: {
    Foo: "foo"
    iCanChoose: "whateverILike"
} @cuetsy(targetType="enum")
export enum MyEnum {
  Foo = "foo",
  iCanChoose = "whateverILike",
}

Defaults

CUE TypeScript
Defaults const

Cuetsy can optionally generate a const for each type that holds default values. For that, attach CUE Default Values to your type definitions:

CUETypeScript
MyUnion: 1 | 2 | *3 @cuetsy(targetType="type")

MyDisjEnum: "foo" | *"bar" @cuetsy(targetType="enum")
MyStructEnum: {
    A: "Foo"
    B: "Bar" @cuetsy(enumDefault)
} @cuetsy(targetType="enum")

MyInterface: {
    num: int | *6
    txt: string | *"CUE"
    enm: MyDisjEnum
} @cuetsy(targetType="interface")
export type MyUnion = 1 | 2 | 3;
export const myUnionDefault: MyUnion = 3;

export enum MyDisjEnum {
  Bar = "bar",
  Foo = "foo",
}
export const myDisjEnumDefault: MyDisjEnum = MyDisjEnum.Bar;

export enum MyStructEnum {
  A = "Foo",
  B = "Bar",
}
export const myStructEnumDefault: MyStructEnum = MyStructEnum.B;

export interface MyInterface {
  enm: MyDisjEnum;
  num: number;
  txt: string;
}
export const myInterfaceDefault: MyInterface = {
  enm: myDisjEnumDefault,
  num: 6,
  txt: "CUE",
};

About

Experimental CUE->TypeScript exporter

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 98.2%
  • Makefile 1.8%