Aleph-Alpha / ts-rs

Generate TypeScript bindings from Rust types
MIT License
1.08k stars 107 forks source link

Fix bug in enum flattening #282

Closed escritorio-gustavo closed 6 months ago

escritorio-gustavo commented 6 months ago

Goal

When a struct containing a flattened enum was itself flattened, the type generated would be missing the enum That is, the following code

#[derive(TS)]
struct FooExternally {
    qux: i32,
    #[ts(flatten)]
    baz: BarExternally,
    biz: Option<String>,
}

#[derive(TS)]
enum BarExternally {
    Baz { a: i32, a2: String },
    Biz { b: bool },
    Buz { c: String, d: Option<i32> },
}

#[derive(TS)]
#[ts(export, export_to = "enum_flattening/externally_tagged/")]
struct NestedExternally {
    #[ts(flatten)]
    a: FooExternally,
    u: u32,
}

Would generate the following TS:

export type NestedExternally = { u: number, qux: number, biz: string | null, };

When it should generate

export type NestedExternally = { u: number, qux: number, biz: string | null, } & (
    | { "Baz": { a: number, a2: string, } }
    | { "Biz": { b: boolean, } }
    | { "Buz": { c: string, d: number | null, } }
);

Changes

Updated the generation of inline_flattened in macros/src/types/named.rs to be similar to inline, except for not removing parenthesis around lonely flattened fields, as that caused issues when flattening a struct that contained only a flattened enum. (The replace(" } & { ", " ") would merge the fields with the first enum variant)

Checklist

NyxCode commented 6 months ago

Nice, thanks!
I never realized that inline_flattened would just drop flattened fields. Amazing that the test suite didnt catch that.

escritorio-gustavo commented 6 months ago

Nice, thanks! I never realized that inline_flattened would just drop flattened fields. Amazing that the test suite didnt catch that.

Me neither! I only realized because I was looking at some old PRs and when I got to #206 I went "wtf was I thinking" lol