Skip to content
/ genus Public

Type Script and Elixir structs, a monster mash

License

Notifications You must be signed in to change notification settings

bwireman/genus

Repository files navigation

Genus

Macro for generating Typescript types and Elixir structs

Installation

def deps do
  [
    {:genus, git: "[email protected]:bwireman/genus.git"}
  ]
end

Usage

defmodule User do
  # load the `tschema` macro
  use Genus
  tschema name: "User" do
    field(:id, :string, required: true)
    field(:email, :string)
    field(:active, :bool, default: false)
    field(:role, :union, "Role", true, [:enduser, :admin, :superuser], default: :enduser)
  end
end

Macro Options

  • name: Name of the generated TypeScript interface, defaults to the last piece of the module name
  • imports: keyword of other imports and import overrides to add to the generated file

Elixir output

defmodule User do
  @enforce_keys [:id]
  defstruct [id: nil, email: nil, active: false, role: :enduser]
end

Typescript output

// Do Not Modify! This file was generated by Genus from an Elixir struct @ Elixir.User
// https://github.com/bwireman/genus

export type Role = "enduser" | "admin" | "superuser"

export interface User {
  id: string
  email?: string
  active: boolean
  role: Role
}

export const apply_user = (v: any): User => v

export const build_user = ({ id, email, active, role }: {
  id: string
  email?: string
  active?: boolean
  role?: Role
}): User => {
  return {
    id: id,
    email: email || undefined,
    active: active || false,
    role: role || "enduser",
  }
}

export const new_user = (id: string) => build_user({ id })

Config

import Config

config :genus,
  # path directory to save the write TypeScript code to
  # defaults to "./ts"
  directory: "types",
  # indent spacer for generated TypeScript
  # defaults to "  "
  indent: "\t"

Types

Format Elixir type TS type
(name, :string) String.t() string
(name, :integer) integer() number
(name, :float) float() number
(name, :bool) bool() boolean
(name) any() any
(name, :external, type_name) any() type_name
(name, :list, type_name) list() type_name[]
(name, :union, type_name, is_string, values) any() type_name

Type Options

  • type_name String.t(): represents the TS type to use
  • is_string bool(): Should the union be represented as strings in TS
  • values list(): Values that compose the union

Field Options

default: value | required: true|false

Fields default to being optional and with a nil default in Elixir and nullable with a default of undefined in TypeScript. If you specify a value that will be the default value in both Elixir and Typescript. You can also specify required: and mark the field as required in both the Elixir struct and the generator function

About

Type Script and Elixir structs, a monster mash

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published