diff --git a/__tests__/produce.ts b/__tests__/produce.ts index c3913873..fd093053 100644 --- a/__tests__/produce.ts +++ b/__tests__/produce.ts @@ -187,6 +187,9 @@ describe("curried producer", () => { let foo = produce((s: State, a: number, b: number) => {}) assert(foo, _ as Recipe) foo(_ as State, 1, 2) + + // @ts-expect-error + foo(undefined, 1, 2) } // Using argument parameters: @@ -743,6 +746,13 @@ it("infers curried", () => { const n = f(base as ROState) assert(n, _ as ROState) // yay! } + { + // explicitly use generic, but curried + const f = produce(draft => { + draft.count++ + }) + assert(f, _ as (state: ROState) => ROState) + } } it("allows for mixed property value types", () => { @@ -758,3 +768,22 @@ it("allows for mixed property value types", () => { } }) }) + +it("#877 - produce with typed state generic requires initial state", () => { + const reducerNoInitial = produce<{count: number}, [{type: "inc"}]>( + (draft, action: {type: "inc"}) => { + if (action.type === "inc") draft.count++ + } + ) + const reducer = produce<{count: number}, [{type: "inc"}]>( + (draft, action: {type: "inc"}) => { + if (action.type === "inc") draft.count++ + }, + {count: 0} + ) + + expect(reducer({count: 0}, {type: "inc"})).toEqual({count: 1}) + expect(reducer(undefined, {type: "inc"})).toEqual({count: 1}) + // @ts-expect-error runtime error without initial state + expect(() => reducerNoInitial(undefined, {type: "inc"})).toThrow() +}) diff --git a/src/types/types-external.ts b/src/types/types-external.ts index d3e7df2c..823643f7 100644 --- a/src/types/types-external.ts +++ b/src/types/types-external.ts @@ -187,12 +187,6 @@ export interface IProduce { > /** Curried producer that infers curried from the State generic, which is explicitly passed in. */ - ( - recipe: ( - state: Draft, - initialState: State - ) => ValidRecipeReturnType - ): (state?: State) => State ( recipe: ( state: Draft,