Skip to content

Support for generating TypeScript union types for non-algebraic enums  #35

@Alfred-Mountfield

Description

@Alfred-Mountfield

In a lot of situations, plain union types are better suited than enums. Ideally there would be some way to make the output of this:

#[derive(Serialize, Deserialize)]
#[typeshare]
pub enum FooBar {
    Foo,
    Bar,
}

be this:

export type FooBar = "Foo" | "Bar"

instead of

export enum FooBar {
    Foo = "Foo",
    Bar = "Bar",
}

I had hoped I'd be able to coerce the generator into doing as desired by using the serde tag attributes:
#[serde(untagged)] is unsupported

#[serde(tag = "type", content = "content")] doesn't work due to

thread '<unnamed>' panicked at 'the serde tag attribute is not supported for non-algebraic enums: FooBar', /Users/foo/.cargo/registry/src/github.com-1ecc6299db9ec823/typeshare-cli-1.0.1/src/main.rs:234:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

If I pollute my Rust code with meaningless newtypes:

#[derive(Serialize, Deserialize)]
#[typeshare]
#[serde(tag = "type", content = "content")]
pub enum FooBar {
    Foo(()),
    Bar(()),
}

Then I do get a TypeScript type that I can then manipulate, but this Rust pollution is not ideal.

export type FooBar = 
	| { type: "Foo", content: undefined }
	| { type: "Bar", content: undefined };

where I can then

import { FooBar as FooBarGen } from "./foobar.gen";

export type FooBar = FooBarGen["type"] // resolves to "Foo" | "Bar"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions