Skip to content

fix(javascript-prop-types): emit .isRequired for required properties#3032

Open
schani wants to merge 8 commits into
masterfrom
agent/fix-issue-1561
Open

fix(javascript-prop-types): emit .isRequired for required properties#3032
schani wants to merge 8 commits into
masterfrom
agent/fix-issue-1561

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Bug

javascript-prop-types never emitted .isRequired, even for properties listed in a JSON Schema's required array. A property like "disabled": { "type": "boolean" } marked required would render as PropTypes.bool instead of PropTypes.bool.isRequired.

Repro

{
  "type": "object",
  "required": ["disabled"],
  "properties": {
    "type": { "type": "string", "enum": ["primary", "secondary"] },
    "disabled": { "type": "boolean" }
  }
}
node dist/index.js --lang javascript-prop-types --src-lang schema schema.json

Before:

_Schema = PropTypes.shape({
    "disabled": PropTypes.bool,
    ...
});

After (matches the issue's expected output):

_Schema = PropTypes.shape({
    "disabled": PropTypes.bool.isRequired,
    ...
});

Root cause

JavaScriptPropTypesRenderer.typeMapTypeFor(t, required = true) had a dead branch — if (required) { return [match]; } just wrapped the value in an array with no effect on the rendered source, so .isRequired was never appended. typeMapTypeForProperty also always called it with the default required = true regardless of the JSON Schema property's actual required/isOptional status, so the flag never correctly reflected "is this property required."

Fix

  • typeMapTypeForProperty now threads through !p.isOptional (and additionally skips .isRequired when the property's type includes null, since PropTypes.isRequired rejects a legitimately-null value for a nullable-but-present property).
  • typeMapTypeFor now actually appends .isRequired to the generated PropTypes validator when required is true, for both primitive/array/union validators and named class/object/enum references.
  • Fixing this exposed two other pre-existing, previously-silent bugs in the same renderer that were only masked because .isRequired was never used:
    • Enums were emitted as PropTypes.oneOfType(['a', 'b']) (raw literals passed to oneOfType, which expects validator functions) instead of PropTypes.oneOf(['a', 'b']). This is now fixed; .isRequired on an enum now works correctly.
    • A required reference to a named class/object type could be a forward reference (the let _Name; declaration is assigned later in emission order), so accessing .isRequired on it eagerly could throw at module-eval time. These references are now wrapped in a small lazily-evaluated function so the property access happens at validation time, once the referenced value is guaranteed to be assigned.
    • Top-level map types now render as PropTypes.objectOf(...) instead of an invalid reference to an undeclared _Name.

Test coverage

  • Added a dedicated schema-javascript-prop-types fixture with one valid sample and six expected-failure samples. It exercises required any, boolean, enum, nested-object, array, and nested properties while leaving an optional property absent.
  • Updated the PropTypes fixture driver to capture validator warnings emitted during generated-module initialization, return round-tripped JSON for positive schema tests, and exit nonzero on validation failures.
  • Added schema-javascript-prop-types to the PropTypes CI fixture group. The regression fixture fails against the pre-fix renderer and passes with this change.

Verification performed locally

  • npm run build
  • npm run lint
  • npm run test:unit — 218 tests pass.
  • QUICKTEST=true FIXTURE=javascript-prop-types,schema-javascript-prop-types npm run test:fixtures — 220 fixture cases pass; the schema case validates one positive and six negative documents.

Fixes #1561

🤖 Generated with Claude Code

…1561)

Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
@schani

schani commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

I think we should be principled with the tests here and figure out a way to test proptypes so that this case can be surfaced by a fixture test. Why can’t we run schema fixtures for proptypes?

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

Generated-output differences

215 files differ — 213 modified, 2 new, 0 deleted
15051 changed lines — +7548 / −7503

Open the generated-output report →

@github-actions

Copy link
Copy Markdown

Generated-output differences

216 files differ — 214 modified, 2 new, 0 deleted
15067 changed lines — +7556 / −7511

Open the generated-output report →

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.

JavaScript PropTypes uses PropTypes.any instead of isRequired

1 participant