• Stars
    star
    300
  • Rank 138,870 (Top 3 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created over 2 years ago
  • Updated 10 months ago

Reviews

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

Repository Details

A library for generating TypeScript definitions from rust code.

Tsify

Tsify is a library for generating TypeScript definitions from Rust code.

Using this with wasm-bindgen will automatically output the types to .d.ts.

Inspired by typescript-definitions and ts-rs.

Example

Click to show Cargo.toml.
[dependencies]
tsify = "0.4.5"
serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = { version = "0.2" }
use serde::{Deserialize, Serialize};
use tsify::Tsify;
use wasm_bindgen::prelude::*;

#[derive(Tsify, Serialize, Deserialize)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub struct Point {
    x: i32,
    y: i32,
}

#[wasm_bindgen]
pub fn into_js() -> Point {
    Point { x: 0, y: 0 }
}

#[wasm_bindgen]
pub fn from_js(point: Point) {}

Will generate the following .d.ts file:

/* tslint:disable */
/* eslint-disable */
/**
 * @returns {Point}
 */
export function into_js(): Point;
/**
 * @param {Point} point
 */
export function from_js(point: Point): void;
export interface Point {
  x: number;
  y: number;
}

This is the behavior due to typescript_custom_section and Rust Type conversions.

Crate Features

  • json (default) enables serialization through serde_json.
  • js enables serialization through serde-wasm-bindgen and generates the appropriate types for it. This will be the default in future versions.

Attributes

Tsify container attributes

  • into_wasm_abi implements IntoWasmAbi and OptionIntoWasmAbi. This can be converted directly from Rust to JS via serde_json or serde-wasm-bindgen.
  • from_wasm_abi implements FromWasmAbi and OptionFromWasmAbi. This is the opposite operation of the above.
  • namespace generates a namespace for the enum variants.

Tsify field attributes

  • type
  • optional

Serde attributes

  • rename
  • rename-all
  • tag
  • content
  • untagged
  • skip
  • skip_serializing
  • skip_deserializing
  • skip_serializing_if = "Option::is_none"
  • flatten
  • default
  • transparent

Type Override

use tsify::Tsify;

#[derive(Tsify)]
pub struct Foo {
    #[tsify(type = "0 | 1 | 2")]
    x: i32,
}

Generated type:

export interface Foo {
  x: 0 | 1 | 2;
}

Optional Properties

#[derive(Tsify)]
struct Optional {
    #[tsify(optional)]
    a: Option<i32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    b: Option<String>,
    #[serde(default)]
    c: i32,
}

Generated type:

export interface Optional {
  a?: number;
  b?: string;
  c?: number;
}

Enum

#[derive(Tsify)]
enum Color {
    Red,
    Blue,
    Green,
    Rgb(u8, u8, u8),
    Hsv {
        hue: f64,
        saturation: f64,
        value: f64,
    },
}

Generated type:

export type Color =
  | "Red"
  | "Blue"
  | "Green"
  | { Rgb: [number, number, number] }
  | { Hsv: { hue: number; saturation: number; value: number } };

Enum with namespace

#[derive(Tsify)]
#[tsify(namespace)]
enum Color {
    Red,
    Blue,
    Green,
    Rgb(u8, u8, u8),
    Hsv {
        hue: f64,
        saturation: f64,
        value: f64,
    },
}

Generated type:

declare namespace Color {
  export type Red = "Red";
  export type Blue = "Blue";
  export type Green = "Green";
  export type Rgb = { Rgb: [number, number, number] };
  export type Hsv = { Hsv: { hue: number; saturation: number; value: number } };
}

export type Color =
  | "Red"
  | "Blue"
  | "Green"
  | { Rgb: [number, number, number] }
  | { Hsv: { hue: number; saturation: number; value: number } };

Type Aliases

use tsify::{declare, Tsify};

#[derive(Tsify)]
struct Foo<T>(T);

#[declare]
type Bar = Foo<i32>;

Generated type:

export type Foo<T> = T;
export type Bar = Foo<number>;