Skip to content

fix(json-schema): recognize $defs when deriving type names#2970

Merged
schani merged 1 commit into
masterfrom
agent/fix-issue-2778
Jul 20, 2026
Merged

fix(json-schema): recognize $defs when deriving type names#2970
schani merged 1 commit into
masterfrom
agent/fix-issue-2778

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Bug

Fixes #2778.

A JSON Schema that defines a type under $defs and references it got a
different, truncated name in generated output than the name given in the
schema. For example, a type named LightParams under $defs was emitted
as Light in generated TypeScript. Renaming $defs to the legacy
definitions keyword in the same schema produced the correct name,
which pointed at the root cause.

Root cause

Ref.definitionName in packages/quicktype-core/src/input/JSONSchemaInput.ts
only recognized the legacy "definitions" JSON Schema keyword, not "$defs"
(the standard keyword for local definitions since draft 2019-09, used by the
2020-12 draft referenced in the issue). Because of this, a type's $defs key
was never treated as a "given name" for the type. The type kept only its
inferred names (e.g. the referencing property name, plus a name derived
from the input file name), and combineNames in
packages/quicktype-core/src/attributes/TypeNames.ts merged those candidates
by common prefix — which produced the truncated/wrong name.

Fix

definitionName now also recognizes "$defs" alongside "definitions":

if (keyOrIndex(pe) === "definitions" || keyOrIndex(pe) === "$defs")
    return keyOrIndex(defined(arrayLast(this.path)));

Test coverage

  • New JSON Schema fixture test/inputs/schema/light.schema +
    test/inputs/schema/light.1.json, reproducing the schema from the issue,
    runs end-to-end (round-trip) for every schema-input language fixture.
  • New unit test test/unit/json-schema-definitions.test.ts asserts the
    generated TypeScript interface is named LightParams, not Light. This
    is a unit test rather than a fixture-only check because fixture tests
    validate round-tripping, not the exact generated symbol name — the actual
    regression here.
  • Checked test/inputs/schema/*.schema for any other existing input using
    $defs; light.schema is the only one, so no other fixture snapshots are
    affected by this change.

Verification

  • npm run build — passes.
  • npm run test:unit — 164/164 tests pass (26 files).
  • Re-ran the exact repro from the issue:
    node dist/index.js --src-lang schema --lang ts --just-types --no-date-times --alphabetize-properties light.schema.json
    
    Before: export interface Light { ... } (referenced as Light).
    After: export interface LightParams { ... } (referenced as LightParams), matching the reporter's expectation.
  • QUICKTEST=true FIXTURE=schema-typescript script/test test/inputs/schema/light.schema — passes.
  • biome check on changed files — clean.
  • Ran the full schema-typescript fixture set locally; confirmed one pre-existing, unrelated failure (vega-lite.schema hits pre-existing TypeScript compile errors, TS2411, on unmodified master as well — unrelated to this change). CI will validate the rest of the language matrix.

🤖 Generated with Claude Code

The definitionName getter in JSONSchemaInput.ts only recognized the
legacy "definitions" keyword, so types defined under the standard
"$defs" keyword (draft 2019-09+) never had their schema-given name
treated as a given name. combineNames then merged the type's other
candidate names by common prefix, producing truncated/wrong names
(e.g. "LightParams" became "Light").

Fix: also recognize "$defs" in definitionName.

Adds a schema fixture (light.schema/light.1.json) exercising the
round trip, and a focused unit test asserting the generated
TypeScript interface keeps its given name, since fixture tests don't
observe generated symbol names.

Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
@schani
schani merged commit 92811f5 into master Jul 20, 2026
28 checks passed
@schani
schani deleted the agent/fix-issue-2778 branch July 20, 2026 22:02
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.

[BUG]: Types are randomly renamed

1 participant