fix(schema): honor single-entry patternProperties as additionalProperties - #3008
Open
schani wants to merge 7 commits into
Open
fix(schema): honor single-entry patternProperties as additionalProperties#3008schani wants to merge 7 commits into
schani wants to merge 7 commits into
Conversation
…ties (#1643) quicktype only used patternProperties in place of additionalProperties when the pattern key was the literal string ".*". Any other pattern (e.g. "(^[A-Za-z0-9]+$)"), including ones that also match every string, was silently ignored, leaving the property with no type information and generating JSONAny/[String: JSONAny] instead of a typed map. Generalize the existing hack: when additionalProperties is unset and patternProperties has exactly one entry, use that entry's schema as the effective additionalProperties, regardless of the pattern text. Multiple patternProperties entries are left as before (unsupported). Added a JSON Schema fixture (test/inputs/schema/pattern-properties.schema + .1.json) covering the reported shape, and a focused unit test asserting the generated Swift output has a typed dictionary value instead of JSONAny. Fixes #1643 Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
cjson does not validate class-element types, so the mistyped map value in pattern-properties.1.fail.json is not rejected. Skip the schema for cjson, matching the existing go-schema-pattern-properties handling. Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # test/languages.ts
…age-3008-merge-1784733649
Generated-output differences26 files differ — 0 modified, 26 new, 0 deleted |
Generated-output differences27 files differ — 0 modified, 27 new, 0 deleted |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
Reported in #1643: a JSON Schema object whose value type is described with
patternProperties(rather thanadditionalProperties) loses all typeinformation when the pattern isn't the literal string
.*. For example:{ "type": "object", "properties": { "alternators": { "type": "object", "patternProperties": { "(^[A-Za-z0-9]+$)": { "type": "object", "properties": { "voltage": { "type": "number" }, "name": { "type": "string" } } } } } } }generated (Swift, but reproducible in every language):
with a warning that quicktype couldn't infer the type, even though the
pattern's schema fully describes the map's value type.
Root cause
packages/quicktype-core/src/input/JSONSchemaInput.tshad a narrow hack(originally added for #976) that only treats
patternPropertiesas a stand-infor
additionalPropertieswhen the single pattern key is exactly".*".Any other pattern — including ones that are effectively "match anything" like
(^[A-Za-z0-9]+$)— was ignored entirely, so the property fell back tountyped
any.Fix
Generalize the existing heuristic: when
additionalPropertiesis notexplicitly set and
patternPropertieshas exactly one entry, use thatentry's schema as the effective
additionalProperties, regardless of whatthe pattern text is. Schemas with multiple
patternPropertiesentries areleft unchanged (still unsupported — out of scope here). The
.*casecontinues to work exactly as before.
Test coverage
test/inputs/schema/pattern-properties.schema+.1.json: new JSON Schemafixture reproducing the reported shape (a
patternPropertiesentry with anon-
.*pattern describing a map of typed sub-objects). This isauto-discovered by the
schema-*fixtures intest/fixtures.ts.test/unit/pattern-properties-schema.test.ts: focused unit test assertingthe generated Swift output contains a typed dictionary value
(
[String: Alternator]?with typedname/voltagefields) and no longercontains
JSONAny..*-pattern fixture(
test/inputs/schema/go-schema-pattern-properties.schema) still passes,confirming no regression to that case.
Verification
npm run buildpasses.npx vitest run test/unit/pattern-properties-schema.test.tspasses.QUICKTEST=true FIXTURE=schema-golang script/test— all 68 schema fixturetests pass, including the new
pattern-properties.schemaand the existinggo-schema-pattern-properties.schema(.*case).node dist/index.js -l swift -s schema --src schema.json): output now showslet alternators: [String: Alternator]?with a generatedAlternatorstruct containing typedname/voltagefields, and the "cannot infer this type" warning is gone.target languages.
Fixes #1643
🤖 Generated with Claude Code