Skip to content

Deriving the TS trait

escritorio-gustavo edited this page Feb 15, 2024 · 26 revisions

#[derive(TS)]

The TS trait can be easily derived through its #[derive(TS)] macro, which will automatically handle mapping a Rust type into TypeScript type definitions.

The #[derive(TS)] macro provides an attribute helper macro called #[ts(...)] which can help you control how the types will be generated

#[ts(...)] attributes

Container attributes

These are attributes that can be used both with structs and enums

#[ts(export)]

This attribute causes the generation of a test which will create a ts file containing the TypeScript declaration for your type, as well as any types it depends on (as long as they implement TS)

#[ts(export_to = "...")]

Allows you to change where your TypeScript file will be generated. The default is ./bindings/TypeName.ts, this path is relative to Cargo.toml.

Usage:

#[derive(ts_rs::TS)]
#[ts(export)]
struct MyStruct {
    foo: String
}

This must be either:

  • An absolute path
  • A path relative to your crate's Cargo.toml

The given path will be treated as a directory if it ends with a / character, in which case a file called TypeName.ts will be created within the given directory, otherwise the path will be treated as a file (even without an extension).

Usage:

#[derive(ts_rs::TS)]
#[ts(export, export_to = "../ts_project/bindings/")] // Note that #[ts(export)] is still required
struct MyStruct {
    foo: String
}

If you see yourself using #[ts_export = "..."] with the same directory for a lot (or even all) your types, there is a more convenient way to do this.

Create a directory at the root of your project (the directory that contains Cargo.toml) called .cargo. Inside the .cargo directory, create a file called config.toml and type the following:

[env]
TS_RS_EXPORT_DIR = { value = "...", relative = true }

Where value is a path to a directory (i.e. it must end with a slash /) relative to your Cargo.toml file.

Now, using #[ts(export)] without #[ts(export_to = "...")] will result in exporting to the directory defined in your config.toml file.

Note that if you use #[ts(export_to = "...")] with this config, the path given to TS_RS_EXPORT_DIR will be concatenated with the path given to export_to as if they were strings, so using ../foo/bar/ in export_to will cause problems, due to a currently unresolved issue with parent components in the middle of paths.

#[ts(rename = "...")]

Changes the name of your type's TypeScript representation.

If the feature flag serde-compat is enabled (default), using #[serde(rename = "...")] will have the same effect.

Usage:

#[derive(ts_rs::TS)]
#[ts(export, rename = "MyType")]
struct MyStruct {
    foo: String
}

Generates:

export type MyType = { foo: string, }

#[ts(rename_all = "...")]

Renames all the fields in your struct or variants in your enum to use a given inflection.

Accepted values are lowercase, snake_case, kebab-case, UPPERCASE, camelCase, PascalCase and SCREAMING_SNAKE_CASE.

If the feature flag serde-compat is enabled (default), using #[serde(rename_all = "...")] will have the same effect.

Usage:

#[derive(ts_rs::TS)]
#[ts(export, rename_all = "camelCase")]
struct MyStruct {
    foo_bar: String
}

Generates:

export type MyStruct = { fooBar: string, }

Struct field attributes

#[ts(inline)]

#[ts(flatten)]

#[ts(as = "...")]

#[ts(type = "...")]

#[ts(optional)]

#[ts(optional = nullable)]

#[ts(skip)]

#[ts(rename = "...")]

Enum attibutes

#[ts(rename_all_fields)]

Equivalent to adding #[ts(rename_all = "..."] to every variant.

Accepted values are lowercase, snake_case, kebab-case, UPPERCASE, camelCase, PascalCase and SCREAMING_SNAKE_CASE.

#[ts(tag = "...")]

#[ts(tag = "...", content = "...")]

#[ts(untagged)]

Enum variant attributes

#[ts(inline)]

#[ts(skip)]

#[ts(rename = "...")]

#[ts(rename_all = "...")]

Clone this wiki locally