Aleph-Alpha/ts-rs

[Question] - How to Derive(ts) for Complex Data Structures from External Crates? #163

Closed this issue · 5 comments

Hello,

I appreciate the ts-rs crate and use it frequently. However, I've encountered some edge cases that I need assistance with. I hope my issue can be resolved, or perhaps I'm just not using ts-rs correctly.

In one of my applications, I use SurrealDB, and it includes a struct called Thing. Here's how Thing and its associated Id enum are defined:

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Deserialize, Store, Hash)]
pub struct Thing {
	pub tb: String,
	pub id: Id,
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
pub enum Id {
	Number(i64),
	String(String),
	Array(Array),
	Object(Object),
}

These shapes of structs are extracted from the surrealdb crate, and I can't modify the code to add derive(TS...).

Currently, my application is throwing the following error:

error[E0277]: the trait bound `surrealdb::sql::Thing: TS` is not satisfied
   ...

As a workaround, I've used the following code:

#[derive(TS, Debug, Serialize, Deserialize)]
#[ts(export, export_to = "../../src/utiles/types_rust_bindings/")]
pub struct User {
    #[ts(type = "string")]
    pub id: Thing,
    ... other fields ...
}

Is there a better approach to address this situation? How can I make my types in TypeScript have the same type as they are presented in SurrealDB structs? Any guidance would be greatly appreciated.

Thank you!

hey, thanks for reaching out.
There are a couple of solutions/workarounds:

  • Create a PR to add support for the types you need, gated behind a feature
  • use the #[ts(type = .. )] override. This works well for simple types. For more complex structs, you could write the type out yourself and put it in a .d.ts file and refer to it in the type override.
  • Create a wrapper type and inplement TS by hand, or implement TS for your entire type by hand

I think the third option will work better for this case. How can I implement the TS? I am little bit new to rust so I do not really know where to look. Do you have any example?

I think the third will be better because this is very complex structure and I need just part of it. Another this type is very specific to surrealdb so it will be better to I think to separate this into external support caret

I think that's the most cumbersome tbh. Can't you just write the TypeScript type of Thing yourself, put it in a surreal.d.ts file, and use #[ts(type = "Thing")] whenever you have a field of type Thing in your structs?

Again, the "real" solution here is to add support for the surrealdb crate in a PR to ts-rs, but someone will have to do that.

I will ask them then thanks @NyxCode