Skip to content

feat(openapi3): extend annotated enum strategy to unions of literals#11154

Open
tellnes wants to merge 1 commit into
microsoft:mainfrom
tellnes:openapi3-annotated-union-literals
Open

feat(openapi3): extend annotated enum strategy to unions of literals#11154
tellnes wants to merge 1 commit into
microsoft:mainfrom
tellnes:openapi3-annotated-union-literals

Conversation

@tellnes

@tellnes tellnes commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Extends enum-strategy: annotated (#10892, which fixed #5721) to unions of literals. That option previously stopped at enum declarations, so unions of literals still collapsed to a flat enum, dropping variant names, @summary, and docs.

/** Set of known error types. */
union ErrorType {
  /** Common error for a bad request. */
  @summary("CommonBadRequest")
  commonBadRequest: "https://example.com/errors/bad-request",
}

Before: { type: string, enum: ["https://example.com/errors/bad-request"] }

After (with enum-strategy: annotated):

ErrorType:
  description: Set of known error types.
  anyOf:
    - const: https://example.com/errors/bad-request
      title: CommonBadRequest
      description: Common error for a bad request.

Behavior

  • Opt-in via the existing option; default output unchanged.
  • 3.1.0/3.2.0 only; 3.0.0 falls back and reports the existing enum-strategy-not-supported warning.
  • oneOf when the union has @oneOf, else anyOf.
  • title from @summary, description from @doc, both omitted when absent, matching the enum handling.
  • Non-literal variants (models/scalars) stay as their own members; discriminated unions untouched.

Open question

The option is named enum-strategy but now also covers unions of literals (both are "enumerated types" in OpenAPI terms). I broadened its description rather than renaming it. Happy to add an alias if preferred.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @typespec/openapi3
Show changes

@typespec/openapi3 - feature ✏️

Extend the enum-strategy: annotated emitter option to unions of literals. When set to annotated, a union whose variants are literals is emitted as a oneOf/anyOf of const subschemas with per-variant title/description taken from @summary and @doc, instead of collapsing to a single lossy enum. Supported for OpenAPI 3.1.0 and above; emitting with OpenAPI 3.0.0 falls back to the default form and reports a warning.,> ,> For example, the following TypeSpec:,> ,> typespec,> /** Set of known error types. */,> union ErrorType {,> /** Common error for a bad request. */,> @summary("CommonBadRequest"),> commonBadRequest: "https://example.com/errors/bad-request",,> ,> /** The request body could not be parsed. */,> @summary("InvalidBody"),> invalidBody: "https://example.com/errors/invalid-body",,> },> ,> ,> emits:,> ,> yaml,> ErrorType:,> description: Set of known error types.,> anyOf:,> - const: https://example.com/errors/bad-request,> title: CommonBadRequest,> description: Common error for a bad request.,> - const: https://example.com/errors/invalid-body,> title: InvalidBody,> description: The request body could not be parsed.,> ,> ,> Use @oneOf on the union to emit oneOf instead of anyOf.

When `enum-strategy: annotated` is set, literal unions now emit as
`oneOf`/`anyOf` of `const` subschemas with per-variant `title` and
`description` from `@summary`/`@doc`, preserving documentation that
the default `enum`-merge form discards. Falls back to default on
OpenAPI 3.0.0 with a warning.
@tellnes tellnes force-pushed the openapi3-annotated-union-literals branch from eff4f41 to ad41540 Compare July 3, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:openapi3 Issues for @typespec/openapi3 emitter meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAPI 3.1 - emit annotated enums

1 participant