diff --git a/__tests__/type-external.ts b/__tests__/type-external.ts index fcf3b2df9..c5eef3ffc 100644 --- a/__tests__/type-external.ts +++ b/__tests__/type-external.ts @@ -1,6 +1,6 @@ import {isType, JSONArray, JSONObject, JSONTypes} from "type-plus" import {Draft} from "../src/types/types-external" -import {createDraft, current, original} from "../src/immer" +import {createDraft, current, original, produce} from "../src/immer" describe("Draft", () => { test("can use JSONTypes as T", () => { @@ -17,6 +17,23 @@ describe("Draft", () => { type A = Draft<[string, number, JSONArray, JSONObject]> isType.equal() }) + + it("can use recursive types containing readonly arrays as T (#839)", () => { + // Same shape as type-fest's JsonValue + type JsonValue = string | number | boolean | null | JsonObject | JsonArray + type JsonObject = {[Key in string]: JsonValue} & { + [Key in string]?: JsonValue | undefined + } + type JsonArray = JsonValue[] | readonly JsonValue[] + + type A = Draft + isType.equal[], A>() + + const base: {readonly items: readonly JsonValue[]} = {items: []} + produce(base, draft => { + draft.items.push({a: [1, "b"]}) + }) + }) }) describe("current() typings", () => { diff --git a/src/types/types-external.ts b/src/types/types-external.ts index d42ab8f24..e599b8217 100644 --- a/src/types/types-external.ts +++ b/src/types/types-external.ts @@ -28,7 +28,7 @@ export type IfAvailable = */ type WeakReferences = IfAvailable> | IfAvailable> -export type WritableDraft = T extends any[] +export type WritableDraft = T extends readonly any[] ? number extends T["length"] ? IsPlainArray extends true ? Draft[]