diff --git a/.changeset/bright-helpers-smile.md b/.changeset/bright-helpers-smile.md new file mode 100644 index 000000000..a62fa8e47 --- /dev/null +++ b/.changeset/bright-helpers-smile.md @@ -0,0 +1,5 @@ +--- +"openapi-typescript-helpers": patch +--- + +Preserve tuple arity when deriving readable and writable types. diff --git a/packages/openapi-fetch/test/read-write-visibility/read-write.test.ts b/packages/openapi-fetch/test/read-write-visibility/read-write.test.ts index b699887af..5e89bfae8 100644 --- a/packages/openapi-fetch/test/read-write-visibility/read-write.test.ts +++ b/packages/openapi-fetch/test/read-write-visibility/read-write.test.ts @@ -1,8 +1,16 @@ +import type { Readable, Writable } from "openapi-typescript-helpers"; import { describe, expect, expectTypeOf, test } from "vitest"; import { createObservedClient } from "../helpers.js"; import type { paths } from "./schemas/read-write.js"; describe("readOnly/writeOnly", () => { + test("preserves tuple arity in readable and writable types", () => { + type Tuple = ["a", "b"] | ["a", "b", "c"]; + + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); + }); + describe("deeply nested $Read unwrapping through $Read", () => { test("$Read should continue recursion when unwrapping $Read", async () => { // This tests the fix for a bug where Readable<$Read> returned U directly diff --git a/packages/openapi-typescript-helpers/src/index.ts b/packages/openapi-typescript-helpers/src/index.ts index 391e0a694..f5fe76cff 100644 --- a/packages/openapi-typescript-helpers/src/index.ts +++ b/packages/openapi-typescript-helpers/src/index.ts @@ -221,8 +221,8 @@ export type Readable = ? never : T extends $Read ? Readable - : T extends (infer E)[] - ? Readable[] + : T extends readonly unknown[] + ? { [K in keyof T]: Readable } : T extends object ? { [K in keyof T as NonNullable extends $Write ? never : K]: Readable } : T; @@ -238,8 +238,8 @@ export type Writable = ? never : T extends $Write ? Writable - : T extends (infer E)[] - ? Writable[] + : T extends readonly unknown[] + ? { [K in keyof T]: Writable } : T extends object ? { [K in keyof T as NonNullable extends $Read ? never : K]: Writable } & { [K in keyof T as NonNullable extends $Read ? K : never]?: never;