From c2544ad16b228cf89f2993ce7e96763118d44ddd Mon Sep 17 00:00:00 2001 From: Oliver Joseph Ash Date: Fri, 17 Jan 2025 10:20:31 +0000 Subject: [PATCH 1/3] Enable `exactOptionalPropertyTypes` --- tsconfig.base.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tsconfig.base.json b/tsconfig.base.json index 8f209a52e9..f53b7ca935 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -20,6 +20,7 @@ "resolveJsonModule": true, "skipLibCheck": true, "strict": true, + "exactOptionalPropertyTypes": true, "target": "ESnext", "types": ["vitest/globals", "vitest/importMeta"] }, From 824d44daef1bf2571e79f3d8c019d2791447f388 Mon Sep 17 00:00:00 2001 From: Oliver Joseph Ash Date: Fri, 17 Jan 2025 10:20:42 +0000 Subject: [PATCH 2/3] Add failing tests --- test/typescript/reducers.test-d.ts | 34 +++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/test/typescript/reducers.test-d.ts b/test/typescript/reducers.test-d.ts index 46266aea92..26e0e17977 100644 --- a/test/typescript/reducers.test-d.ts +++ b/test/typescript/reducers.test-d.ts @@ -1,4 +1,10 @@ -import type { Action, AnyAction, Reducer, ReducersMapObject } from 'redux' +import type { + Action, + AnyAction, + PreloadedStateShapeFromReducersMapObject, + Reducer, + ReducersMapObject +} from 'redux' import { combineReducers } from 'redux' describe('type tests', () => { @@ -265,4 +271,30 @@ describe('type tests', () => { >() } }) + + test('`PreloadedStateShapeFromReducersMapObject` has correct type when given a custom action', () => { + type MyAction = { type: 'foo' } + + // TODO: not sure how to write this test?? + // Expect this to match type `{ nested: string | undefined; }` + type P = PreloadedStateShapeFromReducersMapObject<{ + nested: Reducer + }> + }) + + test('`combineReducer` has correct return type when given a custom action', () => { + type MyAction = { type: 'foo' } + + type State = string + const nested: Reducer = (state = 'foo') => state + + type Combined = { nested: State } + + // Expect no error + const combined: Reducer< + Combined, + MyAction, + Partial + > = combineReducers({ nested }) + }) }) From bf0a41827136837398bcaae52aeeb719af06ccda Mon Sep 17 00:00:00 2001 From: Oliver Joseph Ash Date: Fri, 17 Jan 2025 10:20:48 +0000 Subject: [PATCH 3/3] Fix failing test --- src/types/reducers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/reducers.ts b/src/types/reducers.ts index 146fc137f6..ca234898f2 100644 --- a/src/types/reducers.ts +++ b/src/types/reducers.ts @@ -106,7 +106,7 @@ export type PreloadedStateShapeFromReducersMapObject = M[keyof M] extends ? { [P in keyof M]: M[P] extends ( inputState: infer InputState, - action: UnknownAction + action: ActionFromReducersMapObject ) => any ? InputState : never