tsify
tsify copied to clipboard
Internally tagged enums can generate invalid TS when using non-object types
If you have an enum such as this:
#[derive(Debug, Serialize, Deserialize, Tsify)]
#[serde(tag = "reason")]
pub enum ParseBaseUriError {
MissingTrailingSlash,
UrlParseError(String),
CannotBeABase,
}
then the generated types look as follows:
declare namespace ParseBaseUriError {
export type MissingTrailingSlash = { reason: "MissingTrailingSlash" };
export type UrlParseError = { reason: "UrlParseError" } & string;
export type CannotBeABase = { reason: "CannotBeABase" };
}
And I believe UrlParseError
is unsatisfiable.
I don't really have a good suggestion for how to resolve this, perhaps disallowing new-type like variants, or possibly only ones that contain types that can be mapped to a non-object JS type. For now I have resolved this by picking a different tagging mechanism, or turning the variants into structs, but I thought I'd flag in case there are any other ideas or to allow adding a warning.
I have also noted the same issue, which can quickly be avoided by using both tag
and content
, e.g., something like
#[serde(tag = "_tag", content = "value")]
. With your example above:
#[derive(Debug, Serialize, Deserialize, Tsify)]
#[serde(rename_all = "camelCase", tag = "_tag", content = "value")]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub enum ParseBaseUriError {
MissingTrailingSlash,
UrlParseError(String),
CannotBeABase,
}
results in the following type declaration:
// you can pattern-match on the `_tag` property
export type ParseBaseUriError
= { _tag: "missingTrailingSlash" }
| { _tag: "urlParseError", value: string }
| { _tag: "cannotBeABase" }