Skip to content

Conversation

@cormacrelf
Copy link

@cormacrelf cormacrelf commented Oct 31, 2025

This is a solution for #65. Basically we can't do the conversion inside FromWasmAbi etc, so we just do it outside but make it as ergonomic as possible.

use tsify::Ts;
use tsify::Tsify;
use wasm_bindgen::{prelude::*, JsError};

#[derive(tsify::Tsify, serde::Deserialize, serde::Serialize, Debug)]
pub enum MyEnum {
    Abc,
    Def(u32),
}

#[wasm_bindgen]
pub fn enum_list(array: Vec<Ts<MyEnum>>) -> Result<Ts<MyEnum>, JsError> {
    for js_enum in array {
        let _rust_enum = js_enum.into_rust()?;
        // this is a MyEnum, no type annotations needed
    }
    Ok(MyEnum::Def(3).into_ts()?)
}

These produce exactly the same typescript outputs as before. But there are no memory leaks.

Still working on the extensions to the Tsify trait for ergonomic return values, int terms of naming. Happy to hear comments and concerns.

@siefkenj
Copy link
Collaborator

siefkenj commented Nov 1, 2025

Looks like there are some test failures, but it might not be due to this PR?

Do the existing tests already cover the traits in this PR?

@cormacrelf
Copy link
Author

There is absolutely nothing testing the new code yet.

@cormacrelf
Copy link
Author

cormacrelf commented Nov 5, 2025

Ok, new stuff. The most major changes are:

  • Added a bunch of tests
  • into_ts is the only method added to Tsify trait
  • More helpers like Ts::new_unchecked to reinterpret an existing JsValue
  • new tsify::Error can wrap either serde_json or serde-wasm-bindgen errors. I did not change the return types of existing methods but adding our own error type for the new Ts code is helpful (can add new variants as we wish)
  • More docs on a lot of stuff
  • Imports the README into the crate docs, so docs.rs/tsify is not an empty wasteland

And most importantly

  • Deprecates #[tsify(into_wasm_abi, from_wasm_abi)] including a deprecation warning when you try to use the attributes recommending people use tsify::Ts instead. I have suppressed these for the test code.
warning: use of deprecated constant `_::_::_x`: into_wasm_abi/from_wasm_abi are deprecated as they cause memory leaks (https://github.com/madonoharu/tsify/issues/65). Consider using `tsify::Ts` instead.
 --> tests-e2e/test1/entry_point.rs:6:9
  |
6 | #[tsify(into_wasm_abi, from_wasm_abi)]
  |         ^^^^^^^^^^^^^
  |
  = note: `#[warn(deprecated)]` on by default

Review questions:

  • Is this how you want to handle deprecation?
  • You cannot write Ts<Vec<XXX>>, only Vec<Ts<XXX>>, which means you have to convert in a loop or iterator. This can be a bit unwieldy -- the shortest one-liner is let vec = vec.into_iter().map(|x| x.to_rust()).collect::<Result<_, _>>()?;. I have not actually used tsify much, is there an easier way with type aliasing to a vec? If so we should document that. (Might be nice to have #[derive(Tsify)] #[tsify(transparent)] struct List(Vec<Data>); if there's nothing else.)

@cormacrelf
Copy link
Author

I can also hold off on the deprecation commit until this has been tested a bit more in the wild.

@cormacrelf cormacrelf marked this pull request as ready for review November 5, 2025 04:28
#[wasm_bindgen]
pub fn from_js(point: Point) {}
pub fn from_js(point: Ts<Point>) -> Result<(), JsError> {
let point: Point = point.to_rust()?;
Copy link
Author

@cormacrelf cormacrelf Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially called this .into_rust() but changed to .to_rust() when I made it take &self. But the other APIs (Tsify trait) do not follow this convention, so maybe this is more confusing and it would be better off called into_rust.

use tsify::Tsify;
use tsify::Ts;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsError;
Copy link
Author

@cormacrelf cormacrelf Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note, I am actually the creator of JsError and the non-memory-leaking Result return-throw in wasm-bindgen :)

@siefkenj
Copy link
Collaborator

@cormacrelf Sorry, I lost track of this :-(. Is the PR ready to go?

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

Successfully merging this pull request may close these issues.

2 participants