Skip to content

Support generating discriminated unions from union declarations #335

@bterlson

Description

@bterlson

Today you only get discriminators when you also establish an inheritance hierarchy with some base type, but this seems unnecessary and in some cases undesirable. Especially in the realm of generating natural API shapes between Rust/Swift (use ADTs) and TS (use discriminated unions), something lower level would be appreciated.

One proposal would be something like the following:

model Person {
  name: string;
}

model Place {
  location: string;
}

@discriminator("kind")
union Noun {
  person: Person
  place: Place,
}

The above has all the information we need to generate idiomatic types in both Rust and TS as follows:

  • For Rust, we do nothing with the @Discriminator, the union can be emitted directly as a Rust enum.
    • However the value may be useful if rust needs to deserialize from JSON using e.g. serde, in which case it would likely generate the attribute #[serde(tag = "kind")].
  • For TS, we "push" the field kind into the variants during emit. If a kind field already exists, then either throw an error (without subtyping proposal) or do a type compatibility check (with subtyping proposal).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions