grantila / typeconv

Convert between JSON Schema, TypeScript, GraphQL, Open API and SureType
MIT License
421 stars 8 forks source link

allOf and additionalProperties #15

Closed pihentagy closed 1 year ago

pihentagy commented 2 years ago

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",
ChuckJonas commented 2 years ago

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)

grantila commented 1 year ago

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.