Skip to content

Commit

Permalink
feat: include tuple names in json schema (#613)
Browse files Browse the repository at this point in the history
  • Loading branch information
k-yle authored Sep 19, 2024
1 parent 2422f97 commit 75e599a
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 2 deletions.
1 change: 1 addition & 0 deletions test/programs/type-aliases-tuple-with-names/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type MyTuple = [a: string, b: 123, c?: boolean, ...d: number[]];
24 changes: 24 additions & 0 deletions test/programs/type-aliases-tuple-with-names/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": [
{
"title": "a",
"type": "string"
},
{
"title": "b",
"type": "number",
"const": 123
},
{
"title": "c",
"type": "boolean"
}
],
"minItems": 2,
"additionalItems": {
"title": "d",
"type": "number"
}
}
1 change: 1 addition & 0 deletions test/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ describe("schema", () => {
assertSchema("type-aliases-recursive-anonymous", "MyAlias");
assertSchema("type-aliases-recursive-export", "MyObject");
*/
assertSchema("type-aliases-tuple-with-names", "MyTuple");
assertSchema("type-aliases-tuple-of-variable-length", "MyTuple");
assertSchema("type-aliases-tuple-with-rest-element", "MyTuple");
assertRejection("type-alias-never", "MyNever", {}, {}, /Unsupported type: never/);
Expand Down
12 changes: 10 additions & 2 deletions typescript-json-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -657,12 +657,20 @@ export class JsonSchemaGenerator {
if (tupleType) {
// tuple
const elemTypes: ts.NodeArray<ts.TypeNode> = (propertyType as any).typeArguments;
const fixedTypes = elemTypes.map((elType) => this.getTypeDefinition(elType as any));
const targetTupleType = (propertyType as ts.TupleTypeReference).target;

const fixedTypes = elemTypes.map((elType, index) => {
const def = this.getTypeDefinition(elType as any);
const label = targetTupleType.labeledElementDeclarations?.[index]?.name?.getFullText().trim();
if (label) {
def.title = label;
}
return def;
});
definition.type = "array";
if (fixedTypes.length > 0) {
definition.items = fixedTypes;
}
const targetTupleType = (propertyType as ts.TupleTypeReference).target;
definition.minItems = targetTupleType.minLength;
if (targetTupleType.hasRestElement) {
definition.additionalItems = fixedTypes[fixedTypes.length - 1];
Expand Down

0 comments on commit 75e599a

Please sign in to comment.