Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[FEATURE]: Resolve JSON Schema $dynamicRef specialisations into concrete Dart field types

Open
#3,531 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
45/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
json, typescript
Domain
tooling

Research direction

Reproduce the issue with parameterised.schema.json, increment.schema.json, direction.schema.json, and probe.schema.json using the documented quicktype command. Start by tracing Quicktype's JSON Schema handling for $dynamicRef and $dynamicAnchor. Done means the Dart output gives increment numeric fields and direction enum fields, or reports that this pattern is unsupported with a clear diagnostic.

Written by the indexing model from the issue text.

Description

Issue Type

JSON Schema support / generated Dart types.

Context

  • Quicktype 26.0.0 (CLI)
  • Input: JSON Schema Draft 2020-12
  • Output: Dart
  • Direct invocation, without schema preprocessing or generated-code edits

Description

Two concrete specialisations of a shared $dynamicRef / $dynamicAnchor wrapper lose their bound branch types. Both become the same class with dynamic fields, although one binds numeric values and the other binds a string enum.

Input Data

Save these four files in the same directory. They use only standard Draft 2020-12 keywords and local references.

parameterised.schema.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "parameterised.schema.json",
  "title": "ParameterisedValue",
  "$defs": {
    "leaf": {
      "$dynamicAnchor": "T",
      "not": true
    }
  },
  "type": "object",
  "required": [
    "gender"
  ],
  "additionalProperties": false,
  "properties": {
    "gender": {
      "title": "GenderValues",
      "type": "object",
      "required": [
        "male",
        "female"
      ],
      "additionalProperties": false,
      "properties": {
        "male": {
          "$dynamicRef": "#T"
        },
        "female": {
          "$dynamicRef": "#T"
        }
      }
    }
  }
}

increment.schema.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "increment.schema.json",
  "title": "ParameterisedIncrement",
  "$ref": "./parameterised.schema.json",
  "$defs": {
    "leaf": {
      "$dynamicAnchor": "T",
      "type": "number"
    }
  }
}

direction.schema.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "direction.schema.json",
  "title": "ParameterisedDirection",
  "$ref": "./parameterised.schema.json",
  "$defs": {
    "leaf": {
      "$dynamicAnchor": "T",
      "type": "string",
      "enum": [
        "increase",
        "decrease"
      ]
    }
  }
}

probe.schema.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "probe.schema.json",
  "title": "Probe",
  "type": "object",
  "required": [
    "increment",
    "direction"
  ],
  "additionalProperties": false,
  "properties": {
    "increment": {
      "$ref": "./increment.schema.json"
    },
    "direction": {
      "$ref": "./direction.schema.json"
    }
  }
}

The shared schema uses $dynamicRef: "#T" for its branch values. Each referencing schema binds T using $dynamicAnchor: one to number, the other to the string enum increase | decrease. This follows the pattern described in JSON Schema's generic-types guidance.

The specialisations are siblings in the root object. There is no recursive data structure or nested generic specialisation in this example. Concrete generated classes are sufficient; language-level generics are not required.

Steps to Reproduce

npx --yes --package [email protected] quicktype \
  -s schema --lang dart --src probe.schema.json --out models.dart

Current Behaviour / Output

Generation exits successfully but prints warnings:

quicktype cannot infer this type because there is no data about it in the input.
    final dynamic female;
quicktype cannot infer this type because there is no data about it in the input.
    final dynamic male;

The generated root uses ParameterisedValue for both direction and increment. Their shared branch class is:

class GenderValues {
    final dynamic female;
    final dynamic male;

    GenderValues({
        required this.female,
        required this.male,
    });
}

Expected Behaviour / Output

The increment branches should be numeric, while the direction branches should use an enum for increase | decrease. Concrete specialised classes are sufficient; this does not require generic Dart classes.

The schema contains the branch types through the dynamic bindings. I verified the original four-file schema with Python jsonschema 4.26.0: it accepts a valid numeric/enum payload and rejects string increments or numeric directions.

If dynamic references are currently unsupported, an explicit unsupported-keyword/pattern diagnostic would help distinguish that limitation from genuinely unconstrained input. The desired feature is resolving these bindings into concrete types during generation.

Dominant language
TypeScript
Stars
13.9k
Forks
1.2k
Avg merge
6h 54m
Merged PRs (30d)
80

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from glideapps/quicktype

All issues in glideapps/quicktype

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.