Why does description expand referenced type?
Can I prevent reference type from expansion?
Input JSON:
{
"properties": {
"correct": {
"$ref": "#/definitions/color"
},
"wrong": {
"description": "should be referenced",
"$ref": "#/definitions/color"
}
},
"additionalProperties": false,
"definitions": {
"color": {
"type": "string",
"enum": ["red", "green", "blue"]
}
}
}
Actual output:
export type Color = "red" | "green" | "blue";
export interface Bug {
correct?: Color;
/**
* should be referenced
*/
wrong?: "red" | "green" | "blue";
}
Expected output:
export type Color = "red" | "green" | "blue";
export interface Bug {
correct?: Color;
/**
* should be referenced
*/
wrong?: Color;
}
I investigated this a bit it appears there's two things responsible for this behavior.
The first is that json-schema-to-typescript uses json-schema-ref-parser to dereference referenced definitions:
https://github.com/bcherny/json-schema-to-typescript/blob/8ea10a61f0d4b24749ae033a37f9aa3fb9a94417/src/resolver.ts#L11
From json-schema-ref-parser's docs: "The dereference method maintains object reference equality, meaning that all $ref pointers that point to the same object will be replaced with references to the same object."
And then json-schema-to-typescript uses this referential equality to determine if the types should be referenced or expanded:
https://github.com/bcherny/json-schema-to-typescript/blob/8ea10a61f0d4b24749ae033a37f9aa3fb9a94417/src/parser.ts#L123
But the presence of description on the referencing property breaks this referential equality because the referencing object is now a different object from the definition, and the result is the expanded type.
I'd love to work on a fix for this if the library maintainers have any advice on a good approach. I couldn't think of any solutions given the data available at the point where the referential equality check occurs.
It's worth noting that this is not valid JSON schema in draft-07 and earlier. Support for siblings to a $ref was added in 2019-09. https://json-schema.org/draft/2019-09/release-notes.html
Just ran into this one on a project. Didn't expect the output types to change so drastically when I added a few descriptions to $ref entries