Discriminated Types
TypeSpec allows for the expression of unions and inheritance. However, when transmitting types over the network, many languages require a mechanism to distinguish between different union variants or models within an inheritance hierarchy.
Implementing Discriminated Unions
Unions can be marked as discriminated using the @discriminated
decorator. This discriminator will assume the variant name is the discriminator value.
Default serialization
@discriminatedunion Pet { cat: Cat, dog: Dog,}
Serialize as
{ "kind": "cat", "value": { "name": "Whiskers", "meow": true }}// or{ "kind": "dog", "value": { "name": "Rex", "bark": false }}
Customize properties names
@discriminated(#{ discriminatorPropertyName: "dataKind", envelopePropertyName: "data" })union Pet { cat: Cat, dog: Dog,}
model Cat { name: string; meow: int32;}
model Dog { name: string; bark: string;}
serialize as
{ "dataKind": "cat", "data": { "name": "Whiskers", "meow": true }}// or{ "dataKind": "dog", "data": { "name": "Rex", "bark": false }}
Inject discriminator inline
@discriminated(#{ envelope: "none" })union Pet { cat: Cat, dog: Dog,}
model Cat { name: string; meow: boolean;}
model Dog { name: string; bark: boolean;}
serialize as
{ "kind": "cat", "name": "Whiskers", "meow": true}// or{ "kind": "dog", "name": "Rex", "bark": false}
Implementing Polymorphism
string
Discriminator
@discriminator("kind")model Pet { name: string; weight?: float32;}model Cat extends Pet { kind: "cat"; meow: int32;}model Dog extends Pet { kind: "dog"; bark: string;}
enum
Discriminator
enum PetKind { cat, dog,}
@discriminator("kind")model Pet { kind: PetKind; name: string; weight?: float32;}model Cat extends Pet { kind: PetKind.cat; meow: int32;}model Dog extends Pet { kind: PetKind.dog; bark: string;}
Nested Discriminator
@discriminator("kind")model Pet { kind: string; name: string; weight?: float32;}
@discriminator("breed")model Cat extends Pet { kind: "cat"; breed: string; meow: int32;}
@discriminator("breed")model Siamese extends Cat { breed: "siamese";}
@discriminator("breed")model Bengal extends Cat { breed: "bengal";}
model Dog extends Pet { kind: "dog"; bark: string;}