Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to generate a TS ambient enum? #25

Open
hillin opened this issue Jun 27, 2023 · 2 comments
Open

Is it possible to generate a TS ambient enum? #25

hillin opened this issue Jun 27, 2023 · 2 comments

Comments

@hillin
Copy link

hillin commented Jun 27, 2023

Edit: I'm generalizing this issue.

Currently all rust enums are generated as typescript union types. While this is perfectly valid as rust enums are literally discriminated unions, sometimes we'd expect plain old enums in the declaration file. Apparently the d.ts way is to use ambient enum. Can we do this with tsify?

Original issue:
Title: Is it possible to generate a TS string enum?
String enum in Typescript:
https://www.typescriptlang.org/docs/handbook/enums.html#string-enums

@hillin hillin changed the title Is it possible to generate a TS string enum? Is it possible to generate a TS const enum? Jun 27, 2023
@hillin hillin changed the title Is it possible to generate a TS const enum? Is it possible to generate a TS ambient enum? Jun 27, 2023
@jkomyno
Copy link

jkomyno commented Nov 23, 2023

I've also bumped in this issue. To get C-style / ambient enum declarations, you'd need the serde_repr crate and something like:

use serde_repr::{Deserialize_repr};

#[derive(Debug, PartialEq, Eq, Deserialize_repr, Tsify)]
#[tsify(from_wasm_abi)]
#[repr(u8)]
pub enum AmbientEnum {
    Int32 = 0,
    Int64 = 1,
}

This way, you'd get the correct Rust deserialization logic:

#[wasm_bindgen_test]
fn ambient_enum_test() {
    // Example deserialization code
    let json_data = r#"0"#;
    let n_value = serde_json::from_str::<u32>(&json_data).unwrap();
    let n_value = serde_json::from_str::<i32>(&json_data).unwrap();
    let n_value = serde_json::from_str::<u64>(&json_data).unwrap();
    let n_value = serde_json::from_str::<i64>(&json_data).unwrap();

    let ambient_enum = serde_json::from_str::<AmbientEnum>(&json_data).unwrap();
    assert_eq!(ambient_enum, AmbientEnum::Int32);
}

However, tsify would be confused about the types, and would generate

export type AmbientEnum = "Int32" | "Int64";

rather than

export enum AmbientEnum {
  Int32 = 0,
  Int64 = 1,
}

@madonoharu would you have opinionated ideas about how to solve this? Should tsify be able to recognise #[repr(u8)] declarations on enums, and apply different type generations as per the example above?

@AndreaScn
Copy link

AndreaScn commented Apr 12, 2024

This is the same use case I stumbled upon, thank you all for sharing such examples.
Even if not strictly the same, as a workaround I used enum with namespace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants