Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workaround for foreign types #113

Closed
hut8 opened this issue Aug 12, 2022 · 2 comments · Fixed by #174
Closed

Workaround for foreign types #113

hut8 opened this issue Aug 12, 2022 · 2 comments · Fixed by #174
Labels
difficulty: medium enhancement New feature or request good first issue Good for newcomers

Comments

@hut8
Copy link

hut8 commented Aug 12, 2022

Thanks so much for such a great library. It's very useful and I really appreciate the effort that's been put in!

Much like in #82, many of my structs have foreign types. Two of the ones I have that are probably quite common are url::Url (https://docs.rs/url/latest/url/) and compact_str::CompactString (https://docs.rs/compact_str/latest/compact_str/). I am not a rust expert so if my understanding of the issue is flawed, please forgive me 😄

I believe that because of the orphan rule, a derive macro cannot generate code for a type defined in a different crate. Serde has a workaround: https://serde.rs/remote-derive.html -- I could attempt to implement this for ts-rs if you think this is the right way forward.

For now I'm just generating a string via ts(type = 'string') which is fine but with some types misses quite a bit.

@NyxCode
Copy link
Collaborator

NyxCode commented Aug 29, 2022

Hey, thanks for the kind words!

You're completely right that the orphan rule is the problem here.
For now, the solution was just to add a lot of optional cargo features to ts-rs. When enabled, these then implement TS for the corresponding crate.

I'm not against having something comparable to serde's remote derive. For me, having features like uuid-compat for the most common crates and overriding types with #[ts(type = '..')] has been good enough though.

For this library, it would probably just require one attribute, maybe #[ts(as = some::other::Type)].
If questions come up while implementing this, feel free to ask, happy to help.

@ranmocy
Copy link

ranmocy commented Sep 12, 2022

While as attribute seems could solve the issue, it would be more generic to support Serde with/remote instead?

#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(remote = "ExternalType")]
pub struct ExternalTypeDef {
    #[ts(type = "string[]")]
    pub data: Bytes,
}

#[derive(Debug, Clone, Serialize, Deserialize, TS)]
pub enum MyEnum {
    #[serde(with = "ExternalTypeDef")]
    Some(ExternalType),
    Other(String),
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
difficulty: medium enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants