I want to describe schema of an object which has a property of array type. Items in that array must be of the same type. But two different objects can have different type for items in that array:

// object_1
{
  <...>,
  "array_of_some_type": [1, 2, 3, 4, 5],
  <...>
}

// object_2
{
  <...>,
  "array_of_some_type": ["one", "two", "three"],
  <...>
}

I have tried using of oneOf keyword:

{
  "type": "object",
  "properties": {
    <...>
    "array_of_some_type": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "oneOf": [
          { "type": "number" },
          { "type": "string" },
          { "type": "object" }
        ]
      },
      "additionalItems": false
    },
    <...>
  },
  "required": [ "array_of_some_type" ],
  "additionalProperties": false
}

But it is wrong because this schema is valid for invalid in my case object:

// invalid_object
{
  <...>,
  "array_of_some_type": [1, "two", 3],
  <...>
}

The correct schema can look like:

{
  "type": "object",
  "properties": {
    <...>
    "array_of_some_type": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "type": "number" },
          "additionalItems": false
        },
        {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "type": "string" },
          "additionalItems": false
        },
        {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "type": "object" },
          "additionalItems": false
        }
      ]
    },
    <...>
  },
  "required": [ "array_of_some_type" ],
  "additionalProperties": false
}

BUT there are a lot of duplicates of identical array's properties. Is there any way to tune the second schema to avoid repetitions? Or any other suggestions?

1

There are 1 best solutions below

6
On BEST ANSWER

You can put only the part that varies in the oneOf clause. I think JSON-Schema would have to support something like Java's generics in order to express this any cleaner.

{
  "type": "object",
  "properties": {
    "array_of_some_type": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "oneOf": [
        { "items": { "type": "number" } },
        { "items": { "type": "string" } },
        { "items": { "type": "object" } }
      ]
    }
  },
  "required": [ "array_of_some_type" ],
  "additionalProperties": false
}