typeconv icon indicating copy to clipboard operation
typeconv copied to clipboard

allOf and additionalProperties

Open pihentagy opened this issue 4 years ago • 1 comments

Given the following typescript file:

interface A {
    a: string;
}

interface B {
    b: string;
}

export type C = A & B;

typeconv produces the following json schema:

{
  "definitions": {
    "C": {
      "allOf": [
        {
          "$ref": "#/definitions/A"
        },
        {
          "$ref": "#/definitions/B"
        }
      ],
      "title": "C"
    },
    "A": {
      "type": "object",
      "properties": {
        "a": {
          "type": "string",
          "title": "A.a"
        }
      },
      "required": [
        "a"
      ],
      "additionalProperties": false,
      "title": "A"
    },
    "B": {
      "type": "object",
      "properties": {
        "b": {
          "type": "string",
          "title": "B.b"
        }
      },
      "required": [
        "b"
      ],
      "additionalProperties": false,
      "title": "B"
    }
  },
  "$id": "dummy.json",
  "$comment": "Generated from src/api/dummy.ts by core-types-json-schema (https://github.com/grantila/core-types-json-schema) on behalf of typeconv (https://github.com/grantila/typeconv)"
}

However, the following json will not validate against type C in the schema:

{
  "a": "hello",
  "b": "world"
}

You can check it only at https://www.jsonschemavalidator.net/. You should add the following lines to the beginning of the json schema:

  "type": "object",
  "$ref": "#/definitions/C",

pihentagy avatar Oct 28 '21 11:10 pihentagy

I'm also running into this same issue.

The incompatibility with how ajv validates this is documented here: https://github.com/ajv-validator/ajv/issues/1496.

Apperently the solution is to use "unevaluatedProperties", but it's unclear to me if this would be part of the OpenAPI spec (or even if it's official json schema for that matter)

ChuckJonas avatar Jul 28 '22 14:07 ChuckJonas

Thanks for this!

Intersection types in JSON Schema works differently than in e.g. TypeScript. Merging A and B into one self-contained object C will make this work.

grantila avatar Apr 03 '23 06:04 grantila