Skip to content

Enum

WARNING

There is no enum in JavaScript, and Rust enum is very different from TypeScript enum. You need to read this section carefully before you use Rust enum in JavaScript.

In NAPI-RS, Rust enum is basically transformed into a plain JavaScript Object.

lib.rs
rust
#[napi]
pub enum Kind {
  Duck,
  Dog,
  Cat,
}

⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️

index.d.ts
ts
export const enum Kind {
  Duck,
  Dog,
  Cat,
}

In TypeScript, numeric enum members also get a reverse mapping from enum values to enum names. However, in Rust, we don't have this reverse mapping behavior. It is just a plain JavaScript Object.

Numeric variants default to consecutive i32 values starting at zero. Explicit Rust integer discriminants are preserved, and following implicit variants continue from the previous value.

String enum

lib.rs
rust
#[napi(string_enum)]
pub enum Kind {
  Duck,
  Dog,
  Cat,
}

⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️

index.d.ts
ts
export const enum Kind {
  Duck = 'Duck',
  Dog = 'Dog',
  Cat = 'Cat',
}

Use string_enum = "case" to transform every variant name, or #[napi(value = "...")] on one variant to choose its exact JavaScript value. Supported cases are listed in the #[napi] attribute reference.

lib.rs
rust
#[napi(string_enum = "kebab-case")]
pub enum AccessMode {
  ReadOnly,
  #[napi(value = "read-write")]
  Writable,
}

Structured enum

An enum with a data-carrying variant becomes a discriminated object union rather than a JavaScript enum object.

lib.rs
rust
#[napi]
pub enum Event {
  Ready,
  FileChanged { path: String },
  Progress(u32, u32),
}
index.d.ts
ts
export type Event =
  | { type: 'Ready' }
  | { type: 'FileChanged'; path: string }
  | { type: 'Progress'; field0: number; field1: number }

The discriminator is type by default. Change it with discriminant = "kind", and transform variant values with discriminant_case = "camelCase" or another supported case. Named variant fields keep their names; tuple fields become field0, field1, and so on. A field cannot have the same JavaScript name as the discriminator.

Structured enum conversion is owned: accepting one reads and converts its fields into a Rust enum value, while returning one creates a new JavaScript object. object_from_js = false or object_to_js = false can make the type one-directional. See Type conversions.

NAPI-RS doesn't support generating Rust enum impl into JavaScript.