Skip to content

feat(openapi-v3): Preserve JSON Schema const values as TypeScript literal types#332

Open
sandovalrr wants to merge 1 commit intofabien0102:mainfrom
sandovalrr:feat/json-schema-const-literal-types
Open

feat(openapi-v3): Preserve JSON Schema const values as TypeScript literal types#332
sandovalrr wants to merge 1 commit intofabien0102:mainfrom
sandovalrr:feat/json-schema-const-literal-types

Conversation

@sandovalrr
Copy link
Copy Markdown

Summary

This PR preserves JSON Schema / OpenAPI const constraints as TypeScript literal types in generated output.

Before this change, schemas such as { type: "string", const: "READY" } were widened to string because the shared schema emission path did not recognize const. As a result, generated unions and discriminator-like object branches lost useful literal information.

With this change, supported scalar const values are emitted as their corresponding TypeScript literal types:

  • string -> "VALUE"
  • number -> 123
  • boolean -> true / false
  • null -> null

This applies consistently anywhere schemas are emitted through the existing generator flow, including nested properties and composed schemas.

Root Cause

The shared generator logic in schemaToTypeAliasDeclaration.getType() handled:

  • $ref
  • oneOf / anyOf / allOf
  • enum
  • primitive schema types

but it never handled const.

That meant a schema with const fell through to the normal primitive branches and was widened to string, number, or boolean instead of preserving the literal value.

Implementation

The fix adds explicit scalar-const handling in the generator’s shared schema-to-TypeScript emission path.

Key points:

  • const is handled centrally in schemaToTypeAliasDeclaration.ts
  • supported scalar values are converted to TypeScript literal type nodes
  • nullable: true continues to work for non-null const values
  • composed schemas continue to work because existing recursive composition logic now naturally picks up const in branches
  • existing enum, $ref, and non-const behavior is unchanged

This keeps the change small and aligned with the current architecture.

Tests

Added focused coverage for:

  • top-level string / number / boolean / null const
  • nullable const
  • oneOf / anyOf branches with const
  • allOf with compatible const
  • object oneOf branches with const discriminator-like properties and mixed value types
  • generator-level regression coverage proving const emits literal types while adjacent non-const schemas still generate as before

Scope / Tradeoffs

This PR intentionally supports scalar const values only. Object and array const values are left out of scope to keep the change narrow, maintainable, and reviewer-friendly.

- Introduced `SchemaObjectWithConst` type to support const values in schemas.
- Added tests to verify generation of literal types for string, number, boolean, and null const values.
- Updated `getType` and `getConstType` functions to handle const values correctly.
- Ensured const literals are preserved in adjacent schemas during type generation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant