From f4308d90b89e742a2fe7589bcf963daec2cd26c7 Mon Sep 17 00:00:00 2001 From: Hikaru Yoshino Date: Sat, 27 Jul 2024 01:54:42 +0900 Subject: [PATCH 1/2] Fix: Correct handling of minItems and maxItems with identical values in array schemas - Resolved issue where the generated interface was [] when minItems and maxItems were identical - Now generates a tuple type for such cases - Added test case for OpenAPI specification with minItems and maxItems set to 2 --- .changeset/thick-geckos-compete.md | 5 +++++ .../src/transform/schema-object.ts | 10 ++++++++-- .../test/transform/schema-object/array.test.ts | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 .changeset/thick-geckos-compete.md diff --git a/.changeset/thick-geckos-compete.md b/.changeset/thick-geckos-compete.md new file mode 100644 index 000000000..d3185de52 --- /dev/null +++ b/.changeset/thick-geckos-compete.md @@ -0,0 +1,5 @@ +--- +"openapi-typescript": patch +--- + +Fix: Correct handling of identical minItems and maxItems in array schemas when arrayLength option is true diff --git a/packages/openapi-typescript/src/transform/schema-object.ts b/packages/openapi-typescript/src/transform/schema-object.ts index 42f9dbd26..a087e40a5 100644 --- a/packages/openapi-typescript/src/transform/schema-object.ts +++ b/packages/openapi-typescript/src/transform/schema-object.ts @@ -330,8 +330,14 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor (min !== 0 || max !== undefined) && estimateCodeSize < 30 // "30" is an arbitrary number but roughly around when TS starts to struggle with tuple inference in practice ) { - // if maxItems is set, then return a union of all permutations of possible tuple types - if ((schemaObject.maxItems as number) > 0) { + if (min === max) { + const elements: ts.TypeNode[] = []; + for (let i = 0; i < min; i++) { + elements.push(itemType); + } + return tsUnion([ts.factory.createTupleTypeNode(elements)]); + } + else if ((schemaObject.maxItems as number) > 0) { // if maxItems is set, then return a union of all permutations of possible tuple types const members: ts.TypeNode[] = []; // populate 1 short of min … for (let i = 0; i <= (max ?? 0) - min; i++) { diff --git a/packages/openapi-typescript/test/transform/schema-object/array.test.ts b/packages/openapi-typescript/test/transform/schema-object/array.test.ts index e617df0b0..a6f60898e 100644 --- a/packages/openapi-typescript/test/transform/schema-object/array.test.ts +++ b/packages/openapi-typescript/test/transform/schema-object/array.test.ts @@ -146,6 +146,20 @@ describe("transformSchemaObject > array", () => { }, }, ], + [ + "options > arrayLength: true > minItems: 2, maxItems: 2", + { + given: { type: "array", items: { type: "string" }, minItems: 2, maxItems: 2 }, + want: `[ + string, + string +]`, + options: { + ...DEFAULT_OPTIONS, + ctx: { ...DEFAULT_OPTIONS.ctx, arrayLength: true }, + }, + } + ], [ "options > immutable: true", { From 200000e505636372fec01ee078a9447954796efd Mon Sep 17 00:00:00 2001 From: Hikaru Yoshino Date: Sat, 27 Jul 2024 02:16:54 +0900 Subject: [PATCH 2/2] chore: run lint fix --- packages/openapi-typescript/src/transform/schema-object.ts | 4 ++-- .../test/transform/schema-object/array.test.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/openapi-typescript/src/transform/schema-object.ts b/packages/openapi-typescript/src/transform/schema-object.ts index a087e40a5..59c42b842 100644 --- a/packages/openapi-typescript/src/transform/schema-object.ts +++ b/packages/openapi-typescript/src/transform/schema-object.ts @@ -336,8 +336,8 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor elements.push(itemType); } return tsUnion([ts.factory.createTupleTypeNode(elements)]); - } - else if ((schemaObject.maxItems as number) > 0) { // if maxItems is set, then return a union of all permutations of possible tuple types + } else if ((schemaObject.maxItems as number) > 0) { + // if maxItems is set, then return a union of all permutations of possible tuple types const members: ts.TypeNode[] = []; // populate 1 short of min … for (let i = 0; i <= (max ?? 0) - min; i++) { diff --git a/packages/openapi-typescript/test/transform/schema-object/array.test.ts b/packages/openapi-typescript/test/transform/schema-object/array.test.ts index a6f60898e..59a2fddb7 100644 --- a/packages/openapi-typescript/test/transform/schema-object/array.test.ts +++ b/packages/openapi-typescript/test/transform/schema-object/array.test.ts @@ -158,7 +158,7 @@ describe("transformSchemaObject > array", () => { ...DEFAULT_OPTIONS, ctx: { ...DEFAULT_OPTIONS.ctx, arrayLength: true }, }, - } + }, ], [ "options > immutable: true",