question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Option to generate `if-then-else` schema for union types

See original GitHub issue

Today (v1.0.0) a union type like the following:

export type Fish = {
  animal_type: 'fish';
  found_in: 'ocean' | 'river';
};

export type Bird = {
  animal_type: 'bird';
  can_fly: boolean;
};

export type Animal = Bird | Fish;

Generates the following json schema:

    "Animal": {
      "anyOf": [
        {
          "$ref": "#/definitions/Bird"
        },
        {
          "$ref": "#/definitions/Fish"
        }
      ]
    },

This fulfills the need to validate the schema. However, when there is an error schema validators like ajv produce errors for all schema paths. As an example, { animal_type: 'fish', found_in: 'lake' } results in the following error:

must have required property 'can_fly': can_fly [keyword: required, instancePath: , schemaPath: #/definitions/Bird/required]
must be equal to one of the allowed values: ocean,river [keyword: enum, instancePath: /found_in, schemaPath: #/definitions/Fish/properties/found_in/enum]
must match a schema in anyOf:  [keyword: anyOf, instancePath: , schemaPath: #/anyOf]

This first line in this error can be misleading since animal_type is fish, and can_fly is not a property of fish. The second line is the real error that we’d like to present. The errors can get more confusing as you add more types to the union type… a lot of errors are shown for types that are irrelevant given the provide animal_type.

A solution to this problem would be to have the option to generate if-then-else json schemas. These provide more information to the validators to pick the appropriate schema. So if we generate the following:

    "Animal": {
        "type": "object",
        "properties": {
          "animal_type": {
            "type": "string",
            "enum": ["fish", "bird"]
          }
        },
    "allOf": [
        {
          "if": {
            "properties": { "animal_type": { "const": "fish" } }
          },
          "then": {
            "$ref": "#/definitions/Fish"
          }
        },
        {
          "if": {
            "properties": { "animal_type": { "const": "bird" } }
          },
          "then": {
            "$ref": "#/definitions/Bird"
          }
        }
      ]
    }

The same input results in the following, more concise error:

must be equal to one of the allowed values: ocean,river [keyword: enum, instancePath: /found_in, schemaPath: #/definitions/Fish/properties/found_in/enum]

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
Jason3Scommented, Apr 6, 2022

@mdesousa,

Excellent description.

I would push back on the validators. The validators have all the same information that this tool does. It is nearly impossible to know which field / fields to use as the type pivot. It gets even more complicated when you add sub-types.

The validator should be able to do a “best-fit” and give the appropriate error.

0reactions
github-actions[bot]commented, Sep 21, 2022

🚀 Issue was released in v1.1.0 🚀

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to represent union types in JSON schema validator?
I noticed from http://json-schema.org/draft-07/schema that it supports if then else statements to switch validation schema based on the value, ...
Read more >
fluent-json-schema/API.md at master - GitHub
A fluent API to generate JSON schemas. Contribute to fastify/fluent-json-schema development by creating an account on GitHub.
Read more >
Unions and interfaces - Apollo GraphQL Docs
Unions and interfaces are abstract GraphQL types that enable a schema field to return one of multiple object types. Union type.
Read more >
Strict mode - Ajv JSON schema validator
Union types allowUnionTypes option; Contradictory types; Require applicable types ... The only change that strict mode introduces to JTD schemas, ...
Read more >
Applying Subschemas Conditionally - JSON Schema
Nothing is merged or extended. Both schemas apply independently. For example, here is another way to write the above: { "type" ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found