{"id":25103249,"url":"https://github.com/clemensv/json-cs","last_synced_at":"2025-04-19T17:53:21.267Z","repository":{"id":276333536,"uuid":"900775594","full_name":"clemensv/json-cs","owner":"clemensv","description":"JSON Compact Schema (JSON-CS)","archived":false,"fork":false,"pushed_at":"2025-03-19T02:27:37.000Z","size":11083,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-29T11:12:23.472Z","etag":null,"topics":["json","json-schema"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clemensv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-09T13:00:08.000Z","updated_at":"2025-03-19T02:27:40.000Z","dependencies_parsed_at":"2025-02-07T16:26:48.510Z","dependency_job_id":"a6cf99b2-e6cb-492c-9b0f-d74d76655f6c","html_url":"https://github.com/clemensv/json-cs","commit_stats":null,"previous_names":["clemensv/json-cs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clemensv%2Fjson-cs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clemensv%2Fjson-cs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clemensv%2Fjson-cs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clemensv%2Fjson-cs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clemensv","download_url":"https://codeload.github.com/clemensv/json-cs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249753195,"owners_count":21320675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","json-schema"],"created_at":"2025-02-07T21:40:13.579Z","updated_at":"2025-04-19T17:53:21.258Z","avatar_url":"https://github.com/clemensv.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \"New JSON Schema\"\n\nGo [here](./jsc/json-schema-primer.md)\n\n# JSON Compact Schema (JSON-CS)\n\nAuthor: Clemens Vasters, Microsoft Corporation, clemensv@microsoft.com\n\n**JSON Compact Schema** (JSON-CS) is a compact schema language for the JSON data\nformat. JSON-CS also aims to be a schema definition language that can be used to\ndefine data structures abstractly and share them across programs, databases,\nmessaging systems, and REST APIs.\n\n\u003e The specification document can be found [here](spec/json-cs.md).\n\n- [JSON Compact Schema (JSON-CS)](#json-compact-schema-json-cs)\n  - [Status](#status)\n  - [Motivation](#motivation)\n  - [Goals](#goals)\n  - [Examples](#examples)\n    - [Example 1: Basic Type Definition](#example-1-basic-type-definition)\n    - [Example 2: Reusing JSON Schema Definitions](#example-2-reusing-json-schema-definitions)\n    - [Example 4: Using Alternate Names for Encodings](#example-4-using-alternate-names-for-encodings)\n    - [Example 5: Using Units of Measure](#example-5-using-units-of-measure)\n    - [Example 6: Better Documentation with Examples](#example-6-better-documentation-with-examples)\n    - [Example 7: Using Namespaces](#example-7-using-namespaces)\n    - [Example 8: Declaring the root type of a document](#example-8-declaring-the-root-type-of-a-document)\n    - [Example 9: Sharing Definitions with Restricted Polymorphism](#example-9-sharing-definitions-with-restricted-polymorphism)\n    - [Example 11: Disambiguating Type Unions with Discriminators](#example-11-disambiguating-type-unions-with-discriminators)\n  - [Full Specification](#full-specification)\n\n## Status\n\nThis is an experimental specification for discussion.\n\n## Motivation\n\nJSON-CS schema documents quite intentionally resemble [JSON\nSchema](https://json-schema.org/), and there is a [compatibility mapping](spec/json-cs.md#5-compatibility-with-json-schema-drafts) between\nJSON-CS and JSON Schema, but otherwise this is separate effort.\n\nWhile JSON Schema is popular and widely used, its composition model is\nenormously complex. It's possible to write simple looking JSON Schemas that\ndefine data structures that are nearly impossible to implement consistently in\ncommon programming languages or databases.\n\nThe example below shows a valid Draft-07 JSON Schema that looks innocuous at\nfirst glance, but illustrates some of the issues:\n\n```json\n{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"type\" : \"object\",\n    \"properties\" : {\n      \"1st Option\": { \"type\" : \"string\" },\n      \"2nd Option\": {\n        \"oneOf\" : [\n          {\"$ref\": \"#/definitions/TypeA\" },\n\t  \t    {\"$ref\": \"#/definitions/TypeB\" },\n          {\n            \"type\" : \"object\",\n            \"patternProperties\" : {\n              \"^prop-[a-z]+$\" : { \"type\" : \"string\" }\n            } \n          }\n        ]\n      },\n      \"3rd Option\": { \n        \"type\" : \"object\",\n        \"properties\" : {\n              \"prop-d\" : { \"type\" : \"string\" }\n            },\n        \"allOf\" : [\n          {\"$ref\": \"#/definitions/TypeA\" },\n          {\"$ref\": \"#/definitions/TypeC\" }\n        ]\n      }\n    },\n    \"definitions\": {\n        \"TypeA\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"prop-a\": { \"type\": [\"string\", \"integer\"], \"enum\": [\"foo\", 42] },\n                \"prop-b\": { \"$ref\": \"#/definitions/TypeA\" }\n            },\n            \"anyOf\": [ { \"required\": [\"prop-a\"] }, { \"required\": [\"prop-b\"] } ]            \n        },\n        \"TypeB\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"prop-a\": { \"type\": \"boolean\"},\n                \"prop-b\": { \"$ref\": \"#/definitions/TypeA\" }\n            },\n            \"allOf\": [ { \"required\": [\"prop-a\"] }, { \"required\": [\"prop-b\"] } ]            \n        },\n        \"TypeC\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"prop-c\": { \"type\": \"string\"}\n            }\n        }\n    }  \n}\n```\n\nSome issues:\n\n  - Property names start with numbers, contain whitespace (`1st Option`) or '-'\n    characters (`prop-a`), all of which are not allowed in identifiers of many\n    programming languages and therefore require some form of name mangling.\n  - The `2nd Option` property is defined as an object that can be either of two\n    types, `TypeA` or `TypeB`, or an object with properties whose names match a\n    regular expression. While this may look like a type union, it's really not.\n    The rule is that the object must either match the definition of `TypeA` or\n    `TypeB` or have properties that match the regular expression and are of\n    string type. But if \"prop-a\" from `TypeA` is present (a string), then\n    \"prop-b\" must also be present and be an object that matches `TypeA`, because\n    `{ \"prop-a\": \"foo\" }` matches both `TypeA` and the regular expression and\n    then violates the `oneOf` rule. It's therefore a matching expression and\n    cannot be expresses as a type union definition.\n  - The `3rd Option` property is defined as an object that must match all of\n    `TypeA`, `TypeC`, and may have an optional property `prop-d`. While that is\n    very easily expressed in JSON Schema, it's fairly difficult to map to a\n    programming language or database because the types are distinctly defined\n    and used in other contexts, but are merged into a single definition in this\n    type instance. With a single `allOf` rule entry, this is often used to model\n    type-inheritance in JSON Schema, but the pattern breaks with multiple\n    entries for languages that do not support multiple inheritance.\n  - The `prop-a` property of `TypeA` is defined as a string or integer that must\n    be either \"foo\" or 42. JSON Schema does permit AddIng values of different\n    types in an `enum` list that accompanies a type union and this feature is\n    indeed used \"in the wild\", but this is quite tricky to map to most\n    programming language's type systems.\n  - The `anyOf` clause in `TypeA` is used to define that either `prop-a` or\n    `prop-b` or both (!) must be present. The `allOf` clause in `TypeB` is used\n    to define that both `prop-a` and `prop-b` must be present. However, this is\n    achieved through composition of multiple `required` clauses, which is not a\n    feature of most programming languages.\n    \n\nIf you believe these issues are contrived, browsing\n[schemastore.org](https://www.schemastore.org/json/) will hopefully convince you\notherwise. The [\"JFrog Pipeline\"\nschema](https://json.schemastore.org/jfrog-pipelines.json) is a good example of\na schema whose types are very difficult to map to a programming language.\n\nIf you say \"well, that's just a terribly complicated schema\", then you're\nabsolutely correct.\n\nJSON Schema allows you to write terribly complicated schemas and all tools that\ntry to map JSON Schema to programming language data structures or to database\ntables simply throw up their hands and give up at some point of complexity. None\nof them agree on where that point is and it's impossible for you to know ahead\nof time whether a schema you write will work with a given toolchain unless you\nlimit yourself to a very small subset of JSON Schema.\n\nJSON-CS aims to make it easier to write schemas that can be consistently\nimplemented in programming languages and databases and to put constraints in\nplace that don't leave the author guessing whether a schema can indeed be used\nto describe data structures that can be used across a variety of tools.\n\nA further motivation for JSON-CS is that the JSON Schema specifications are\nwritten such that they need an extra documentation website to explain them to\npractitioners. The JSON-CS specification is one self-contained document that\naims to be concrete and understandable to practitioners.\n\n## Goals\n\nA key design goal for JSON-CS is that schemas should look familiar and be\ninstantly understandable to someone who knows JSON Schema. \n\nHowever, the goal is not to be a replacement for JSON Schema, but to be a\nsimpler, far more constrained schema language that can describe data structures\nthat are expressible in JSON and that can be easily mapped to and from\nprogramming language data structures and database tables. \n\nAs such, it is not a goal to provide composition and validation features that\ncan cover all imaginable complexities that may occur in JSON documents. \n\nJSON-CS is not a subset of JSON Schema. JSON-CS puts substantial constraints on\ndefinitions and adds a number of important features that are not present in JSON\nSchema and that aim to improve the quality of the metadata that can be expressed\nin a schema:\n\n- **Strict Typing**: JSON-CS requires explicit type declarations for each\n  object property.\n- **Strict Naming**: JSON-CS imposes strict naming rules for properties and\n  types that aim to be compatible with programming languages and databases. Also,\n  the naming and namespace rules ensure that each declared type has a unique\n  name.\n- **Self-Contained**: JSON-CS schemas must be self-contained and do not allow\n  external references to other schemas.\n- **Modularity**: JSON-CS explicitly supports namespaces and allows organizaing\n  a lage number of type definitions within a single file. It also supports type\n  definition hierarchies [where types can reuse shared definitions from abstract\n  types](spec/json-cs.md#376-reuse-of-type-definitions-with-restricted-polymorphism),\n  but without imposing the complexity of full subtype-polymorphism.\n- **Internationalization**: JSON-CS supports alternate names and alternate symbols\n  for properties and enums to support\n  [internationalization](spec/json-cs.md#3342-alternate-names-for-display-internationalization).\n- **Alternate Identifiers**: JSON-CS supports alternate names for properties and\n  types to support mapping to programming languages and databases and\n  [serialization\n  formats](spec/json-cs.md#3341-alternate-names-for-json-encoding), like you can\n  define a serialization-specific identifier for a property that is different\n  from the property name.\n- **Precise semantics**: JSON-CS requires explicit type declarations for each\n  property and adds a [`unit`](spec/json-cs.md#3772-the-unit-keyword) attribute\n  for properties to declare SI units or other units of measure for the property.\n- **Richer descriptions**: JSON-CS adds an\n  [`examples`](spec/json-cs.md#3773-the-examples-keyword) attribute to\n  properties to provide examples of a type's values.\n\n## Examples\n\n### Example 1: Basic Type Definition\n\nThis is a basic type definition for a `Person` object with a few properties.\nThe definition is quasi identical to a JSON Schema definition, but with the\naddition of the `$schema` keyword that identifies the document as a JSON-CS\ndocument.\n\n```json\n{\n    \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n    \"name\": \"Person\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"id\": { \"type\": \"string\" },\n        \"title\": { \"type\": \"string\" },\n        \"firstName\": { \"type\": \"string\" },\n        \"lastName\": { \"type\": \"string\" },\n        \"dateOfBirth\": { \"type\": \"string\", \"format\": \"date\" },\n    },\n    \"required\": [\"id\", \"lastName\"]\n}\n```\n\n### Example 2: Reusing JSON Schema Definitions\n\nJSON-CS processors [must recognize the schema identifiers of JSON\nSchema](spec/json-cs.md#5-compatibility-with-json-schema-drafts) and process\nthem as JSON-CS documents, but within the constraints of JSON-CS. JSON-CS\nprocessors will allow you to reuse many existing, simple JSON Schema documents\nas JSON-CS documents.\n\nThe following example shows a JSON Schema document that defines an `Address`,\n`Label`, and `Person` type. The `Person` type references the `Address` and\n`Label` types, the latter as an array of `Label` objects.\n\n```json\n{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"title\": \"Person\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"id\": { \"type\": \"string\" },\n        \"title\": { \"type\": \"string\" },\n        \"firstName\": { \"type\": \"string\" },\n        \"lastName\": { \"type\": \"string\" },\n        \"dateOfBirth\": { \"type\": \"string\", \"format\": \"date\" },\n        \"address\": { \"$ref\": \"#/definitions/Address\" },\n        \"labels\": {\n            \"type\": \"array\",\n            \"items\": { \"$ref\": \"#/definitions/Label\" }\n        }\n    },\n    \"required\": [\"id\", \"lastName\"],\n    \"definitions\": {\n        \"Address\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"street\": { \"type\": \"string\" },\n                \"city\": { \"type\": \"string\" },\n                \"zip\": { \"type\": \"string\" }\n            },\n            \"required\": [\"street\", \"city\", \"zip\"]\n        },\n        \"Label\": {\n          \"type\": \"object\",\n          \"properties\": {\n              \"name\": { \"type\": \"string\" },\n              \"value\": { \"type\": \"string\" },\n          }\n        }\n    }\n}\n```\t\n\nThis schema is a valid JSON-CS definition through the compatibility mapping,\nwith the types defined in the `definitions` section being placed into the \nempty (global) namespace.\n\nThat means that the vast majority of existing JSON Schema documents used \nto describe simple data structures can be used as JSON-CS documents without\nmodification, also for contexts like OpenAPI.\n\n### Example 3: Using Alternate Names for Internationalization\n\nThis example shows how to use alternate names for properties to support\ninternationalization. The `name` property has alternate names for Spanish and\nChinese that can be shown as labels in a user interface instead of the technical\nidentifier.\n\n```json\n{\n    \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n    \"Product\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"name\": {\n                \"type\": \"string\",\n                \"altnames\": {\n                    \"display:es\": \"Nombre\",\n                    \"display:zh\": \"名称\"\n                }\n            }\n        },\n        \"required\": [\"name\"],\n        \"additionalProperties\": false\n    }\n}\n```\n\n### Example 4: Using Alternate Names for Encodings\n\nThis example shows how to use alternate names for properties to support mapping\nto programming languages and databases. The `productName` property has an\nalternate name for JSON encoding that is different from the property name.\n\n```json\n{\n    \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n    \"Product\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"productName\": {\n                \"type\": \"string\",\n                \"altnames\": {\n                    \"json\": \"product-name\"\n                }\n            }\n        },\n        \"required\": [\"name\"],\n        \"additionalProperties\": false\n    }\n}\n```\n\nFor declaring types that can be consistently translated into Protocol Buffers\nschemas, the `altnames` attribute could be used to declare the numeric tag for\nthe field in the Protocol Buffers schema. This mapping is not defined in the\nspecification, but can be defined as a convention for a JSON-CS to Proto\ntranslation mapping. \n\n```json\n{\n    \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n    \"Product\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"productName\": {\n                \"type\": \"string\",\n                \"altnames\": {\n                    \"protoId\": \"1\"\n                }\n            }\n        },\n        \"required\": [\"name\"],\n        \"additionalProperties\": false\n    }\n}\n```\n\n### Example 5: Using Units of Measure\n\nThis example shows how to use the `unit` attribute to declare the unit of measure\nfor a property. The `weight` property is declared to be a number with a unit of\nmeasure of kilograms.\n\n```json\n{\n    \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n    \"Product\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"weight\": {\n                \"type\": \"number\",\n                \"unit\": \"kg\"\n            }\n        },\n        \"required\": [\"weight\"],\n        \"additionalProperties\": false\n    }\n}\n```\n\n### Example 6: Better Documentation with Examples\n\nThis example shows how to use the `examples` attribute to provide examples of\nvalues for a property. The `weight` property is declared to be a number with a\nunit of measure of kilograms. The `examples` attribute provides two examples of\nvalues for the `weight` property.\n\n```json\n{\n    \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n    \"Product\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"weight\": {\n                \"type\": \"number\",\n                \"unit\": \"kg\",\n                \"examples\": [\n                  { \"value\": 2.5, \"description\": \"A typical weight for this product\" },\n                  { \"value\": 3.0, \"description\": \"A heavier weight for this product\" }\n                ]\n            }\n        },\n        \"required\": [\"weight\"],\n        \"additionalProperties\": false\n    }\n}\n```\n\n### Example 7: Using Namespaces\n\nThis example shows how to use namespaces to organize type\ndefinitions within a single file. \n\n```json\n{\n  \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n  \"Orders\": {\n    \"Order\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"id\": { \"type\": \"string\" },\n        \"customer\": { \"$ref\": \"#/Customers/Customer\" },\n        \"items\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/Inventory/Item\" } }\n      },\n      \"required\": [\"id\", \"customer\", \"items\"]\n    },\n    \"Invoice\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"id\": { \"type\": \"string\" },\n        \"order\": { \"$ref\": \"#/Orders/Order\" },\n        \"total\": { \"type\": \"number\" }\n      },\n      \"required\": [\"id\", \"order\", \"total\"]\n    },\n    \"Payment\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"id\": { \"type\": \"string\" },\n        \"invoice\": { \"$ref\": \"#/Orders/Invoice\" },\n        \"amount\": { \"type\": \"number\" }\n      },\n      \"required\": [\"id\", \"invoice\", \"amount\"]\n    }\n  },\n  \"Inventory\": {\n    \"Item\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"id\": { \"type\": \"string\" },\n        \"name\": { \"type\": \"string\" },\n        \"price\": { \"type\": \"number\" }\n      },\n      \"required\": [\"id\", \"name\", \"price\"]\n    }\n  },\n  \"Customers\": {\n    \"Customer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"id\": { \"type\": \"string\" },\n        \"name\": { \"type\": \"string\" },\n        \"email\": { \"type\": \"string\" }\n      },\n      \"required\": [\"id\", \"name\", \"email\"]\n    }\n  }\n}\n```\n\n### Example 8: Declaring the root type of a document\n\nThis example shows how to declare the root type of a document. The `Order` type\nis declared as the root type of the document even though it is declared inside\nthe `Orders` namespace.\n\n```json\n{\n  \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n  \"$root\": \"#/Orders/Order\",\n  \"Orders\" : {\n    \"Order\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"id\": { \"type\": \"string\" },\n        \"customer\": { \"$ref\": \"#/Customers/Customer\" },\n        \"items\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/Inventory/Item\" } }\n      },\n      \"required\": [\"id\", \"customer\", \"items\"]\n    }\n  }\n}\n```\n\n### Example 9: Sharing Definitions with Restricted Polymorphism\n\nThis example shows how to share definitions with restricted polymorphism. The\n`Vehicle` type is an abstract type that defines a `make` property. The `Car` and\n`Truck` types are concrete types that extend the `Vehicle` type and add\nadditional properties.\n\nWhile this looks like subtype polymorphism at first glance, it's more\nrestricted. The `Vehicle` type is abstract and cannot be used directly. It must\nonly be used in the `$extends` clause of a concrete type. The `Car` and `Truck`\ntypes are concrete types that extend the `Vehicle` type and add additional\nproperties. The `Car` and `Truck` types cannot be used interchangeably where a\n`Vehicle` type is expected because it's not permitted to declare a property as\nhaving a type of `Vehicle`.\n\n```json\n{\n  \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n  \"Vehicle\": {\n    \"type\": \"object\",\n    \"abstract\": true,\n    \"properties\": {\n      \"make\": { \"type\": \"string\" }\n    },\n    \"required\": [\"make\"]\n  },\n  \"Car\": {\n      \"type\": \"object\",\n      \"$extends\": \"#/Vehicle\",\n      \"properties\": {\n        \"seats\": { \"type\": \"number\" }\n      },\n      \"required\": [\"seats\"]\n  },\n  \"Truck\": {\n      \"type\": \"object\",\n      \"$extends\": \"#/Vehicle\",\n      \"properties\": {\n        \"loadCapacity\": { \"type\": \"number\" }\n      },\n      \"required\": [\"loadCapacity\"]\n  }\n}\n```\n\nIt is possible to define a property that can be either a `Car` or a `Truck` by\nusing a union type. The items in the `vehicles` array of the `Fleet` type show\nthis. That means that polymorphism can be modeled, but it must be explicit and\nrestricted to the types that are defined in the schema.\n\n```json\n{\n  \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n  \"Vehicle\": {\n    \"type\": \"object\",\n    \"abstract\": true,\n    \"properties\": {\n      \"make\": { \"type\": \"string\" }\n    },\n    \"required\": [\"make\"]\n  },\n  \"Car\": {\n      \"type\": \"object\",\n      \"$extends\": \"#/Vehicle\",\n      \"properties\": {\n        \"seats\": { \"type\": \"number\" }\n      },\n      \"required\": [\"seats\"]\n  },\n  \"Truck\": {\n      \"type\": \"object\",\n      \"$extends\": \"#/Vehicle\",\n      \"properties\": {\n        \"loadCapacity\": { \"type\": \"number\" }\n      },\n      \"required\": [\"loadCapacity\"]\n  },\n  \"Fleet\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"vehicles\": {\n        \"type\" : \"array\",\n        \"items\": [\n          { \"$ref\": \"#/Car\" },\n          { \"$ref\": \"#/Truck\" }\n        ]\n      }\n    },\n    \"required\": [\"vehicles\"]\n  }\n}\n```\n\n### Example 11: Disambiguating Type Unions with Discriminators\n\nThis example shows how to identify types and therefore disambiguate type unions\nwith discriminators. The `Vehicle` type is an abstract type that defines a\n`make` property. The `Car` and `Truck` types are concrete types that extend the\n`Vehicle` type and add additional properties. The `Vehicle` type has a `type`\nproperty that is used as a discriminator to determine the concrete type of the\nobject.\n\nThe `const` keyword is used to declare the fixed value of the `type` property\nthat indicates the concrete type of the object. The `const` value is used at\ndesign time and at runtime to ensure that the alternative types are mutually\nexclusive even if all their properties are optional.\n\n```json\n{\n  \"$schema\": \"https://schemas.microsoft.com/experimental/json-cs/v0\",\n  \"Vehicle\": {\n    \"type\": \"object\",\n    \"abstract\": true,\n    \"properties\": {\n      \"type\": { \"type\": \"string\" },\n      \"make\": { \"type\": \"string\" }\n    },\n    \"required\": [\"type\", \"make\"]\n  },\n  \"Car\": {\n      \"type\": \"object\",\n      \"$extends\": \"#/Vehicle\",\n      \"properties\": {\n        \"type\": { \"type\": \"string\", \"const\": \"Car\" },\n        \"seats\": { \"type\": \"number\" }\n      },\n      \"required\": [\"type\"]\n  },\n  \"Truck\": {\n      \"type\": \"object\",\n      \"$extends\": \"#/Vehicle\",\n      \"properties\": {\n        \"type\": { \"type\": \"string\", \"const\": \"Truck\" },\n        \"loadCapacity\": { \"type\": \"number\" }\n      },\n      \"required\": [\"type\"]\n  }\n}\n```\n\n## Full Specification\n\nFor the complete JSON-CS specification, please refer to the [JSON-CS (Compact Schema) Specification](spec/json-cs.md).\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclemensv%2Fjson-cs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclemensv%2Fjson-cs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclemensv%2Fjson-cs/lists"}