mafintosh/is-my-json-valid

Allow null to pass on any type

alallier opened this issue · 4 comments

In some cases it might be useful to allow null to pass given any check for type.

For example given the following JSON:

{
  "a": 1234,
  "b": null,
  "c": {
    "d": 4321,
    "e": true
  }
}

We may construct our rules like this:

{
  "required": true,
  "type": "object",
  "properties": {
    "a": {
      "required": true,
      "type": "number"
    },
    "b": {
      "required": true,
      "type": "null"
    },
    "c": {
      "required": true,
      "type": "object",
      "properties": {
        "d": {
          "required": true,
          "type": "number"
        },
        "e": {
          "required": true,
          "type": "boolean"
        }
      }
    },
}

Now say we want to allow b to be a boolean when it is defined but also allow it be null.

We can update our rules to look like this:

{
  "required": true,
  "type": "object",
  "properties": {
    "a": {
      "required": true,
      "type": "number"
    },
    "b": {
      "required": true,
      "type": "null" || "boolean"
    },
    "c": {
      "required": true,
      "type": "object",
      "properties": {
        "d": {
          "required": true,
          "type": "number"
        },
        "e": {
          "required": true,
          "type": "boolean"
        }
      }
    },
}

But if we cant d to be a nested object like originally shown or null using the same trick for b (see rule below) that will error because if is d is in fact null it will try to read a property that doesn't exist

{
  "required": true,
  "type": "object",
  "properties": {
    "a": {
      "required": true,
      "type": "number"
    },
    "b": {
      "required": true,
      "type": "null" || "boolean"
    },
    "c": {
      "required": true,
      "type": "null" || "object",
      "properties": {
        "d": {
          "required": true,
          "type": "number"
        },
        "e": {
          "required": true,
          "type": "boolean"
        }
      }
    },
}

I'm not even sure if the || is valid but it does work in the case when the type isn't object but it would be nice to have something like allowNull key.

So the rules could like something like this:

{
  "required": true,
  "type": "object",
  "properties": {
    "a": {
      "required": true,
      "type": "number"
    },
    "b": {
      "required": true,
      "type": "boolean",
      "allowNull": true
    },
    "c": {
      "required": true,
      "type": "object",
      "allowNull": true,
      "properties": {
        "d": {
          "required": true,
          "type": "number"
        },
        "e": {
          "required": true,
          "type": "boolean"
        }
      }
    },
}

Doesn't passing the type as an array work?

"type": ["null", "array"]

Yes it does! Thank you very much. Might want to throw that in the docs?

Yeah that could be nice, although I don't think that we mention anything about how JSON schema actually works att all. The array thing is just part of regular JSON schema, and isn't special to this implementation...

Right I agree, but it isn't clear that you allow more than one type to be checked by providing an array?