impl_custom_tsify

Macro impl_custom_tsify 

Source
macro_rules! impl_custom_tsify {
    ($type_name:ident $(< $($generics:ident),+ >)?, $decl:literal) => { ... };
}
Expand description

Implements tsify::Tsify with the given type declaration for the given rust type (structs and enums) identifier.

This is the same as what tsify::Tsify derive macro does internally for a given type but with full customization capability, as both are a sugar for wasm_bindgen typescript_custom_section attr plus extern C block defining a wrapped wasm_bindgen::JsValue for the given type. Therefore, this macro (unlike tsify derive macro) puts representative wasm_bindgen::JsValue of the given type on the current scope identified by prepending “Js” to the orginial type identifier, meaning it would be accessible by for example: JsSomeType when original type is SomeType.

This is very usefull for cases where a rust type is not defined in current module (like autogen types) and tsify::Tsify trait cannot be implemented for as a result, so this will implement Tsify trait for the given type and also allows to manually serialize/deserialize the wasm_bindgen::JsValue to/from js side from/to the rust type, for example with custom serializers and deserializers.

Example:

ⓘ
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SomeType {
    pub field: String,
    pub other_field: u8,
}
impl_custom_tsify!(
    SomeType,
    // this will become the typescript
    // interface bindings for SomeType
    "export interface SomeType {
        field: string;
        otherField: number;
    };"
);

#[wasm_bindgen]
pub fn some_fn(arg: JsSomeType) -> JsSomeType {
    // deserialize the arg which is a wrapped `JsValue`
    // into rust `SomeType` using serde_wasm_bindgen
    let val = serde_wasm_bindgen::from_value::<SomeType>(arg.obj).unwrap_throw();

    // body

    // serialize to JsValue optionally with serializer available
    // options and wrap it in JsSomeType for return
    let ser = serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true);
    JsSomeType { obj: val.serialize(ser).unwrap_throw() }
}