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

Bug: structs with flattened enums produce invalid TS #43

Open
vuorioi opened this issue Aug 15, 2024 · 1 comment
Open

Bug: structs with flattened enums produce invalid TS #43

vuorioi opened this issue Aug 15, 2024 · 1 comment

Comments

@vuorioi
Copy link

vuorioi commented Aug 15, 2024

I run into an issue regarding the types generated for structs with flattened enums.

For example when I define:

#[derive(Tsify)]
pub struct Root {
    pub id: usize,
    pub name: String,
    #[serde(flatten)]
    pub root_type: RootType,
}

#[derive(Tsify)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum RootType {
    Type1,
    Type2 {
        extra: bool,
    },
}

the following TS gets generated:

export type RootType = { type: "type1" } | { type: "type2"; extra: boolean };

export interface Root extends RootType {
    id: number;
    name: string;
}

The problem lies in the interface Root extends RootType statement which results in the following error being emitted by tsc:

An interface can only extend an object type or intersection of object types with statically known members.(2312)

and at least in vscode intellisense doesn't pickup the type correctly.

I couldn't find any macro attributes that would result in the correct TS output but maybe I'm missing something. Other than manually changing the TS Root definition to use type instead of interface a workaround is to change the Rust Root to an enum:

#[derive(Tsify)]
#[serde(untagged)]
pub enum Root {
    Root {
        id: usize,
        name: String,
        #[serde(flatten)]
        root_type: RootType,
    }
}

which yields a working TS definition, albeit at the expense of the Rust side ergonomics:

export type Root = { id: number; name: string } & RootType;

I get the same behavior with both 0.5.4 and 27d6982.

If this is truly a bug and not a user error I can try to have a peek under the hood at some point, but that being said I don't have a ton of experience with Rust macros so it will likely take some time 😀

@vuorioi vuorioi changed the title Bug: structs with flattened enums produce invalid TS Bug: structs with flattened enums produces invalid TS Aug 15, 2024
@vuorioi vuorioi changed the title Bug: structs with flattened enums produces invalid TS Bug: structs with flattened enums produce invalid TS Aug 15, 2024
@siefkenj
Copy link
Owner

This is unfortunately a bug :-(. The original tsify author was not keen on switching interface to type, but it does make extending union types impossible...Probably enums should be written as types and struct should be written as interface.

One possible consequence is an interaction with generics. Since interfaces can handle generics better than types in typescript.

I would welcome a PR that tested out using type for generating the type of an enum (and maybe a flag to use an interface instead?)

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

2 participants