typescriptrustwasm-bindgen

Flatten Rust struct with extra `id` property back to TypeScript single object in return of wasm-bindgen function


I am using wasm-bindgen to pass data from rust code to an existing TypeScript codebase. In my TypeScript I have two interfaces, a InvoiceSchema and an InvoiceWithId. The only difference is that InvoiceWithId also has an id property.

interface InvoiceSchema { billTo: string, email: string }
interface InvoiceWithId extends InvoiceSchema { id: string }

I understand in Rust, you can't inherit from another struct and add the extra id property so I have created a struct:

struct InvoiceWithId {
  pub id: String
  pub schema: InvoiceSchema
}

At some point I do need to merge this into a single object for the existing TypeScript code.

How should I convert and pass these objects back to TypeScript so the id property is part of the base object? i.e.

{ id: string, billTo: string, email: string }

Solution

  • You should be able to do this using the serde-wasm-bindgen crate, which lets you serialize Rust structs to JavaScript values using their serde Serialize implementation.

    #[derive(serde::Serialize)]
    #[serde(rename_all = "camelCase")]
    struct InvoiceSchema {
        pub bill_to: String,
        pub email: String,
    }
    
    #[derive(serde::Serialize)]
    struct InvoiceWithId {
        pub id: String,
        #[serde(flatten)]
        pub schema: InvoiceSchema,
    }
    
    #[wasm_bindgen]
    fn get_invoice_with_id() -> JsValue {
        let invoice_with_id = InvoiceWithId { ... };
    
        serde_wasm_bindgen::to_value(&invoice_with_id).unwrap()
    }