Skip to content

fix(ts): added propertyNames support to ts - #3122

Open
carloscasellas wants to merge 1 commit into
glideapps:masterfrom
carloscasellas:agent/issue-1959
Open

fix(ts): added propertyNames support to ts#3122
carloscasellas wants to merge 1 commit into
glideapps:masterfrom
carloscasellas:agent/issue-1959

Conversation

@carloscasellas

Copy link
Copy Markdown

Description

Adds support for JSON Schema's propertyNames keyword when it restricts an object's keys to a finite set of strings (via enum or const). Previously this constraint was silently ignored.

  • For TypeScript, a map whose keys are restricted this way is now generated as Partial<Record<"key1" | "key2", V>> instead of an unconstrained index signature.
  • For JavaScript, the runtime converter now validates incoming keys against the allowed set and rejects unknown ones.
  • If some of the restricted keys are also required, they're expanded into explicit (non-optional) class properties rather than left as an unconstrained map.
  • Flow, Python, Go, and other languages are intentionally unaffected — they keep their existing (unconstrained) map/dict output, since they either lack the type-system feature to express it or it was out of scope for this change.

Related Issue

Fixes #1959

Motivation and Context

propertyNames restricting keys to an enum was ignored entirely, so { [key: string]: T } was generated with nothing indicating which keys are actually allowed — losing type safety and letting invalid keys through undetected at runtime in JS/TS.

Previous Behaviour / Output

Given a schema like:

{
  "languages": {
    "type": "object",
    "propertyNames": { "type": "string", "enum": ["de", "en"] },
    "additionalProperties": { "type": "object", "properties": { "name": { "type": "string" } } }
  }
}

TypeScript generated:

languages: { [key: string]: Language };

with no indication that only de and en are valid keys, and the JS runtime converter accepted any key.

New Behaviour / Output

TypeScript now generates:

languages: Partial<Record<"de" | "en", Language>>;

and the JavaScript runtime converter rejects any key outside ["de", "en"] with an invalidValue error.

If a subset of the allowed keys is also required, they become explicit properties, e.g.:

de?: Language;
en:  Language;

How Has This Been Tested?

  • New fixture test test/inputs/schema/property-names.schema, with a positive sample (property-names.1.json, property-names.2.json) and a negative sample (property-names.1.fail.property-names.json) that must be rejected at runtime by languages declaring the new property-names feature (TypeScript, JavaScript, Flow — enabled in test/languages.ts).
  • New unit test suite test/unit/property-names-schema.test.ts (12 tests) covering:
    • enum/const constraints producing Partial<Record<...>>
    • keys staying optional (not a bare Record<...>)
    • required keys expanding into explicit properties
    • the contradiction case (required + additionalProperties: false) still erroring
    • non-finite constraints (pattern, mixed-type enum, $ref) correctly leaving the map unconstrained
    • key escaping for non-identifier strings
    • Flow, Python, and Go outputs remaining unchanged
  • Ran tsc --noEmit on quicktype-core — clean.
  • npm run test:unit — all passing.

@carloscasellas carloscasellas changed the title fix(ts): added proprtyNames support to ts fix(ts): added propertyNames support to ts Aug 16, 2026
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.

TypeScript: Keys are not enforced to be Enums

1 participant