Skip to content

fix(typescript): emit top-level aliases for bare map schemas#2991

Merged
schani merged 9 commits into
masterfrom
agent/fix-issue-2642
Jul 23, 2026
Merged

fix(typescript): emit top-level aliases for bare map schemas#2991
schani merged 9 commits into
masterfrom
agent/fix-issue-2642

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

The bug

Reported in #2642: converting an empty-object JSON Schema ({"type":"object","properties":{}}) to TypeScript or Flow produced no usable public type declaration.

  • With --just-types: empty output.
  • Without it: converter boilerplate referenced an inline map type, but no exported top-level alias existed.

Root cause

An empty-object schema is represented as a top-level MapType. TypeScriptFlowBaseRenderer.emitTypes emitted aliases only for primitive and array top levels, while named classes, enums, and unions were handled separately. A bare map therefore fell through both paths.

The fix

emitTypes now reuses namedTypeToNameForTopLevel, the renderer's existing naming decision. If a nested named type claims the top-level name, no alias is emitted; otherwise the top level gets a declaration. This:

  • emits export type EmptySchema = { [key: string]: unknown }; (or Flow's mixed equivalent) for the reported case;
  • avoids duplicate declarations for maps whose value is a named object;
  • composes with fix(typescript): preserve all top-level arrays #3083's top-level-array behavior without separate array-specific logic;
  • preserves the existing non-exported primitive alias behavior.

Test coverage

  • Added empty-object.schema with positive and negative samples for fixture coverage.
  • Added TypeScript and Flow unit coverage for the emitted map alias and duplicate-name regression.
  • Kept fixture skips only for renderers/drivers with pre-existing bare-map validation or generation limitations.

Verification

  • npm run build
  • npm run lint
  • npm run test:unit (233 passed after conflict resolution)
  • focused TypeScript/Flow alias tests (8 passed after final simplification)
  • schema-typescript empty-object fixture passed
  • Flow fixture could not run locally because flow is not installed; Flow rendering is covered by the unit test and CI

Fixes #2642.

schani and others added 2 commits July 20, 2026 17:06
Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
Co-Authored-By: Claude <noreply@anthropic.com>
schani and others added 4 commits July 20, 2026 20:30
The bare empty-object.1.fail.json (a non-object array) runs for every
language, but the Elixir emitter renders a bare top-level map as a
Jason.decode!/encode! pass-through with no shape validation, so it
accepts the array and round-trips it instead of exiting nonzero. This is
the same permissiveness class as go-schema-pattern-properties, which
Elixir already skips. Skip empty-object.schema for Elixir; the positive
and negative cases still run for all other schema languages (verified
locally with schema-javascript and schema-golang).

Co-Authored-By: Claude <noreply@anthropic.com>
#2991)

The Haskell fixture driver encodes a failed decode's Maybe result as the
JSON literal null and exits 0, so expected-failure schema samples can
never be detected — already documented and worked around for
nested-intersection-union.schema, prefix-items.schema, and
direct-union.schema. The new empty-object.schema fixture (added earlier
on this branch) hits the same limitation; add it to the same skip group.

Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
Resolve additive skipSchema conflicts in test/languages.ts by keeping
both the empty-object.schema skips from this branch and the
integer-before-number.schema skips from master.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

Generated-output differences

34 files differ — 6 modified, 28 new, 0 deleted
1882 changed lines — +1878 / −4

Open the generated-output report →

@github-actions

Copy link
Copy Markdown

Generated-output differences

39 files differ — 10 modified, 29 new, 0 deleted
1945 changed lines — +1941 / −4

Open the generated-output report →

schani added 2 commits July 23, 2026 16:36
# Conflicts:
#	packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptFlowBaseRenderer.ts
@schani schani changed the title fix(typescript): emit top-level alias for bare map/array schemas fix(typescript): emit top-level aliases for bare map schemas Jul 23, 2026
@github-actions

Copy link
Copy Markdown

Generated-output differences

31 files differ — 2 modified, 29 new, 0 deleted
1929 changed lines — +1929 / −0

Open the generated-output report →

@schani
schani merged commit 1a87378 into master Jul 23, 2026
30 checks passed
@schani
schani deleted the agent/fix-issue-2642 branch July 23, 2026 22:33
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]: cant convert empty object to dts

2 participants