diff --git a/test/programs/type-aliases-tuple-with-names/main.ts b/test/programs/type-aliases-tuple-with-names/main.ts new file mode 100644 index 0000000..d594c52 --- /dev/null +++ b/test/programs/type-aliases-tuple-with-names/main.ts @@ -0,0 +1 @@ +export type MyTuple = [a: string, b: 123, c?: boolean, ...d: number[]]; diff --git a/test/programs/type-aliases-tuple-with-names/schema.json b/test/programs/type-aliases-tuple-with-names/schema.json new file mode 100644 index 0000000..e33e486 --- /dev/null +++ b/test/programs/type-aliases-tuple-with-names/schema.json @@ -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" + } +} diff --git a/test/schema.test.ts b/test/schema.test.ts index d296250..3effcb1 100644 --- a/test/schema.test.ts +++ b/test/schema.test.ts @@ -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/); diff --git a/typescript-json-schema.ts b/typescript-json-schema.ts index 8471203..f2730b8 100644 --- a/typescript-json-schema.ts +++ b/typescript-json-schema.ts @@ -657,12 +657,20 @@ export class JsonSchemaGenerator { if (tupleType) { // tuple const elemTypes: ts.NodeArray = (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];