Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e5a57df
Discriminated union v2
timotheeguerin Feb 19, 2025
8240234
.
timotheeguerin Feb 19, 2025
ae89d11
Add test in compiler
timotheeguerin Feb 19, 2025
976d754
Discriminated union
timotheeguerin Feb 19, 2025
4486fb1
discriminated union
timotheeguerin Feb 19, 2025
453addf
Create discriminated-union-v2-2025-1-19-20-47-47.md
timotheeguerin Feb 19, 2025
eab7a52
Create discriminated-union-v2-2025-1-19-20-47-47-2.md
timotheeguerin Feb 19, 2025
3a9bace
.
timotheeguerin Feb 19, 2025
e440ea1
fix
timotheeguerin Feb 19, 2025
df90564
Create discriminated-union-v2-2025-1-19-21-9-3.md
timotheeguerin Feb 19, 2025
48c2ddd
tweaks
timotheeguerin Feb 20, 2025
c8a99f9
Merge branch 'discriminated-union-v2' of https://github.com/timotheeg…
timotheeguerin Feb 20, 2025
e6c7cda
Fix
timotheeguerin Feb 20, 2025
8c9091a
handle variant for discriminated unions
timotheeguerin Feb 20, 2025
0674c46
Create discriminated-union-v2-2025-1-20-20-20-31.md
timotheeguerin Feb 20, 2025
049bec4
Merge branch 'main' into discriminated-union-v2
timotheeguerin Feb 20, 2025
69d4e56
fix
timotheeguerin Feb 20, 2025
685369f
fix
timotheeguerin Feb 20, 2025
5daf6e7
.
timotheeguerin Feb 20, 2025
bcd1723
Update .chronus/changes/discriminated-union-v2-2025-1-19-21-9-3.md
timotheeguerin Feb 20, 2025
a61f375
Update packages/openapi3/src/schema-emitter-3-0.ts
timotheeguerin Feb 20, 2025
f02b45f
Update packages/openapi3/src/schema-emitter-3-1.ts
timotheeguerin Feb 20, 2025
b3e34a0
.
timotheeguerin Feb 20, 2025
f2cba79
.
timotheeguerin Feb 20, 2025
8adaedd
Merge branch 'main' into discriminated-union-v2
timotheeguerin Feb 20, 2025
5f7f667
update docs
timotheeguerin Feb 20, 2025
92ae7fb
Merge branch 'main' into discriminated-union-v2
timotheeguerin Feb 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/compiler"
---

Add new `@discriminated` decorator to represent discriminated union with implicit envelopes
14 changes: 14 additions & 0 deletions .chronus/changes/discriminated-union-v2-2025-1-19-20-47-47.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: deprecation
packages:
- "@typespec/compiler"
---

Deprecate use of `@discriminator` on union. Migrate to `@discriminated`

```diff lang="tsp"
-@discriminator("type")
+@discriminated(#{envelope: "none", discriminatorPropertyName: "type"})
union Pet;
```
8 changes: 8 additions & 0 deletions .chronus/changes/discriminated-union-v2-2025-1-19-21-9-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/openapi3"
---

Add support for new `@disriminated` unions
6 changes: 6 additions & 0 deletions .chronus/changes/discriminated-union-v2-2025-1-20-13-58-27.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
changeKind: internal
packages:
- "@typespec/http-specs"
---

6 changes: 6 additions & 0 deletions .chronus/changes/discriminated-union-v2-2025-1-20-20-20-31.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: internal
packages:
- "@typespec/emitter-framework"
---
69 changes: 69 additions & 0 deletions packages/compiler/generated-defs/TypeSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import type {
UnionVariant,
} from "../src/core/index.js";

export interface DiscriminatedOptions {
readonly envelope?: "object" | "none";
readonly discriminatorPropertyName?: string;
readonly envelopePropertyName?: string;
}

export interface ExampleOptions {
readonly title?: string;
readonly description?: string;
Expand Down Expand Up @@ -567,6 +573,68 @@ export type EncodedNameDecorator = (
name: string,
) => void;

/**
* Specify that this union is discriminated.
*
* @param options Options to configure the serialization of the discriminated union.
* @example
* ```typespec
* @discriminated
* union Pet{ cat: Cat, dog: Dog }
*
* model Cat { meow: boolean }
* model Dog { bark: boolean }
* ```
* Serialized as:
* ```json
* {
* "kind": "cat",
* "value": {
* "name": "Whiskers",
* "meow": true
* }
* },
* {
* "kind": "dog",
* "value": {
* "name": "Rex",
* "bark": false
* }
* }
* ```
* @example Custom property names
*
* ```typespec
* @discriminated(#{discriminatorPropertyName: "dataKind", envelopePropertyName: "data"})
* union Pet{ cat: Cat, dog: Dog }
*
* model Cat { meow: boolean }
* model Dog { bark: boolean }
* ```
* Serialized as:
* ```json
* {
* "dataKind": "cat",
* "data": {
* "name": "Whiskers",
* "meow": true
* }
* },
* {
* "dataKind": "dog",
* "data": {
* "name": "Rex",
* "bark": false
* }
* }
* ```
*/
export type DiscriminatedDecorator = (
context: DecoratorContext,
target: Union,
options?: DiscriminatedOptions,
) => void;

/**
* Specify the property to be used to discriminate this type.
*
Expand Down Expand Up @@ -1089,6 +1157,7 @@ export type TypeSpecDecorators = {
overload: OverloadDecorator;
projectedName: ProjectedNameDecorator;
encodedName: EncodedNameDecorator;
discriminated: DiscriminatedDecorator;
discriminator: DiscriminatorDecorator;
example: ExampleDecorator;
opExample: OpExampleDecorator;
Expand Down
77 changes: 77 additions & 0 deletions packages/compiler/lib/std/decorators.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,83 @@ extern dec projectedName(
*/
extern dec encodedName(target: unknown, mimeType: valueof string, name: valueof string);

/**
* Options for `@discriminated` decorator.
*/
model DiscriminatedOptions {
/**
* How is the discriminated union serialized.
* @default object
*/
envelope?: "object" | "none";

/** Name of the discriminator property */
discriminatorPropertyName?: string;

/** Name of the property envelopping the data */
envelopePropertyName?: string;
}

/**
* Specify that this union is discriminated.
* @param options Options to configure the serialization of the discriminated union.
*
* @example
*
* ```typespec
* @discriminated
* union Pet{ cat: Cat, dog: Dog }
*
* model Cat { meow: boolean }
* model Dog { bark: boolean }
* ```
* Serialized as:
* ```json
* {
* "kind": "cat",
* "value": {
* "name": "Whiskers",
* "meow": true
* }
* },
* {
* "kind": "dog",
* "value": {
* "name": "Rex",
* "bark": false
* }
* }
* ```
*
* @example Custom property names
*
* ```typespec
* @discriminated(#{discriminatorPropertyName: "dataKind", envelopePropertyName: "data"})
* union Pet{ cat: Cat, dog: Dog }
*
* model Cat { meow: boolean }
* model Dog { bark: boolean }
* ```
* Serialized as:
* ```json
* {
* "dataKind": "cat",
* "data": {
* "name": "Whiskers",
* "meow": true
* }
* },
* {
* "dataKind": "dog",
* "data": {
* "name": "Rex",
* "bark": false
* }
* }
* ```
*/
extern dec discriminated(target: Union, options?: valueof DiscriminatedOptions);

/**
* Specify the property to be used to discriminate this type.
* @param propertyName The property name to use for discrimination
Expand Down
Loading
Loading