Skip to content

fix type error handler to handle allOf conflicting type - #101

Merged
jdesrosiers merged 6 commits into
hyperjump-io:mainfrom
srivastava-diya:main
Dec 13, 2025
Merged

jdesrosiers merged 6 commits into
hyperjump-io:mainfrom
srivastava-diya:main

Conversation

@srivastava-diya

@srivastava-diya srivastava-diya commented Dec 1, 2025 •

Copy link
Copy Markdown
Contributor

Add Conflicting Type Detection to type Error Handler

This update implements support for detecting conflicting type constraints entirely within the type error handler, as recommended. The previously skipped “ allOf conflicting type” test passes with this change in type error handler.

This fixes : #99

To keep the existing type logic isolated and safe, the changes made are as follows:

  • Starting with a set of all allowed JSON types:

    let allowedTypes = new Set(["null", "boolean", "number", "string", "array", "object", "integer"]);

  • now we intersect it with the type set from each type keyword found at the same instance location. If the resulting set becomes empty, that means the schema’s type constraints are mutually exclusive, so I return a single getConflictingTypeMessage(). If the intersection is not empty, then it isn’t a conflict and the normal type-error handling continues as usual.

  • This keeps allOf functioning purely as a simple applicator while placing all conflict detection logic inside the type handler, as intended.

I’ve implemented this and run the full test suite — all tests pass.

@jdesrosiers jdesrosiers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a couple notes and I pushed some additional tests to expose some gaps we need to fill. There were two main issues. One is dealing with "integer" because it's not a true JSON type and has some overlap with "number". The other issue is about removing duplicate type messages. There should only ever be one per schema.

Comment thread src/error-handlers/type.js Outdated
Comment thread src/error-handlers/type.js Outdated
Signed-off-by: Diya <diyasrivastava2023@gmail.com>
Comment thread src/error-handlers/type.js Outdated
Comment thread src/error-handlers/type.js Outdated
Comment thread src/error-handlers/type.js Outdated
const errors = [];

if (normalizedErrors["https://json-schema.org/keyword/type"]) {
let allowedTypes = new Set(ALL_TYPES);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no reason to create a new set every time you initialize allowedTypes. ALL_TYPES can be a set.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed that, ALL_TYPES is now a set instead of an array

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still creating a new set unnecessarily.

Suggested change
let allowedTypes = new Set(ALL_TYPES);
let allowedTypes = ALL_TYPES;

Comment thread src/error-handlers/type.js Outdated

@jdesrosiers jdesrosiers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there. A couple more things to clean up.

Comment thread src/error-handlers/type.js Outdated
const errors = [];

if (normalizedErrors["https://json-schema.org/keyword/type"]) {
let allowedTypes = new Set(ALL_TYPES);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still creating a new set unnecessarily.

Suggested change
let allowedTypes = new Set(ALL_TYPES);
let allowedTypes = ALL_TYPES;

Comment thread src/keyword-error-message.test.js Outdated
@srivastava-diya

Copy link
Copy Markdown
Contributor Author

Almost there. A couple more things to clean up.

Hey @jdesrosiers
This one is regarding the creation of new set while declaring allowedTypes in let allowedTypes = ALL_TYPES;

Since I’m used to C++, where assignment makes a deep copy, I had to remind myself that JavaScript Set works differently. Here assigning a Set just passes the reference and any change to allowedType would also mutate ALL_TYPES ,but if we look at our code then any mutation never happens on ALL_TYPE because we are performing intersection on allowedTypes before any mutation which returns a new Set anyways hence the code works just fine. But i still think we should stick to let allowedTypes = new Set(ALL_TYPES); for the sake of clarity. I may be wrong please help me with the right thing.

Example:

const ALL_TYPES = new Set(["number", "string", "integer"]);
let allowedTypes = ALL_TYPES;
allowedTypes.delete("integer");

console.log(ALL_TYPES); 

Set(2) { 'number', 'string' }

@jdesrosiers

Copy link
Copy Markdown
Collaborator

@srivastava-diya, I appreciate the effort you're putting into code clarity. I see what you mean, but I think it's clear enough without recreating the set. It feels wrong to me to recreate the set and I don't think it takes too much to understand why it works.

@srivastava-diya

Copy link
Copy Markdown
Contributor Author

@srivastava-diya, I appreciate the effort you're putting into code clarity. I see what you mean, but I think it's clear enough without recreating the set. It feels wrong to me to recreate the set and I don't think it takes too much to understand why it works.

I understand your point @jdesrosiers . And i've done what you suggested.

@jdesrosiers jdesrosiers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@jdesrosiers
jdesrosiers merged commit bf5d5dd into hyperjump-io:main Dec 13, 2025
1 check passed
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.

allOf conflicting type

2 participants