json-schema-to-typescript
json-schema-to-typescript copied to clipboard
Property type changes from "unknown" to "{[k: string]: unknown}" when adding a description to the schema
When generating typescript types for json-patch as defined at http://json.schemastore.org/json-patch, I found the output slightly suspicious, which I wanted to pick up here.
When I input the following string (where I just added a "type": "object" to the oneOf-items):
{
"title": "JSON schema for JSONPatch files",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"required": ["value", "op", "path"],
"properties": {
"path": { "$ref": "#/definitions/path" },
"op": {
"description": "The operation to perform.",
"type": "string",
"enum": ["add", "replace", "test"]
},
"value": {
"description": "The value to add, replace or test."
}
}
},
{
"type": "object",
"additionalProperties": false,
"required": ["op", "path"],
"properties": {
"path": { "$ref": "#/definitions/path" },
"op": {
"description": "The operation to perform.",
"type": "string",
"enum": ["remove"]
}
}
},
{
"type": "object",
"additionalProperties": false,
"required": ["from", "op", "path"],
"properties": {
"path": { "$ref": "#/definitions/path" },
"op": {
"description": "The operation to perform.",
"type": "string",
"enum": ["move", "copy"]
},
"from": {
"$ref": "#/definitions/path",
"description": "A JSON Pointer path pointing to the location to move/copy from."
}
}
}
]
},
"definitions": {
"path": {
"description": "A JSON Pointer path.",
"type": "string"
}
}
}
I get the following result:
/* tslint:disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/
/**
* A JSON Pointer path.
*/
export type Path = string;
export type JSONSchemaForJSONPatchFiles = (
| {
path: Path;
/**
* The operation to perform.
*/
op: "add" | "replace" | "test";
/**
* The value to add, replace or test.
*/
value: {
[k: string]: unknown;
};
}
| {
path: Path;
/**
* The operation to perform.
*/
op: "remove";
}
| {
path: Path;
/**
* The operation to perform.
*/
op: "move" | "copy";
/**
* A JSON Pointer path.
*/
from: string;
}
)[];
You may notice the property value of the first object - it is generated as if I had defined it as an object with arbitrary properties of unknown type. Now, when I remove the property description of its definition (the resulting definition is here):
{
"title": "JSON schema for JSONPatch files",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"required": ["value", "op", "path"],
"properties": {
"path": { "$ref": "#/definitions/path" },
"op": {
"description": "The operation to perform.",
"type": "string",
"enum": ["add", "replace", "test"]
},
"value": {}
}
},
{
"type": "object",
"additionalProperties": false,
"required": ["op", "path"],
"properties": {
"path": { "$ref": "#/definitions/path" },
"op": {
"description": "The operation to perform.",
"type": "string",
"enum": ["remove"]
}
}
},
{
"type": "object",
"additionalProperties": false,
"required": ["from", "op", "path"],
"properties": {
"path": { "$ref": "#/definitions/path" },
"op": {
"description": "The operation to perform.",
"type": "string",
"enum": ["move", "copy"]
},
"from": {
"$ref": "#/definitions/path",
"description": "A JSON Pointer path pointing to the location to move/copy from."
}
}
}
]
},
"definitions": {
"path": {
"description": "A JSON Pointer path.",
"type": "string"
}
}
}
... the result looks as I would've expected it:
/* tslint:disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/
/**
* A JSON Pointer path.
*/
export type Path = string;
export type JSONSchemaForJSONPatchFiles = (
| {
path: Path;
/**
* The operation to perform.
*/
op: "add" | "replace" | "test";
value: unknown;
}
| {
path: Path;
/**
* The operation to perform.
*/
op: "remove";
}
| {
path: Path;
/**
* The operation to perform.
*/
op: "move" | "copy";
/**
* A JSON Pointer path.
*/
from: string;
}
)[];
Is this a bug? Looks like it to me, since the pre- or absense of a description on a property shouldn't change its type, as of my understanding. I would like to have the description in place while still keeping it as type unknown.
This is a bug, and I agree with the proposed behavior. We should also update empty schemas (see test/e2e/emptySchema.ts) to emit:
// Expected
type EmptySchema = unknown
// Actual
export interface EmptySchema {
[k: string]: unknown;
}