From 886215cefa6b4b41e1eb760c7d930298efc3b382 Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 31 Jan 2019 14:45:33 -0800 Subject: [PATCH] reduced typings some more --- playground/src/actions/index.ts | 9 +++++---- playground/src/reducers/createReducer.ts | 11 ++++++----- playground/src/redux-utils/action.ts | 5 +++++ playground/src/redux-utils/reducer.ts | 19 ++++++++++--------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/playground/src/actions/index.ts b/playground/src/actions/index.ts index de4eb75..01d17f3 100644 --- a/playground/src/actions/index.ts +++ b/playground/src/actions/index.ts @@ -1,4 +1,4 @@ -import { action } from '../redux-utils/action'; +import { action, GenericActionTypes, GenericAction, GenericActionLookup, GenericActionMapping } from '../redux-utils/action'; export const actions = { add: (label: string) => action('add', { label }), @@ -9,6 +9,7 @@ export const actions = { filter: (filterTypes: string) => action('filter', { filter: filterTypes }) }; -export type ActionTypes = ReturnType['type']; -export type TodoAction = ReturnType; -export type TodoActionLookup = { [a in ActionTypes]: ReturnType }; +export type ActionMap = GenericActionMapping; +export type ActionTypes = GenericActionTypes; +export type TodoAction = GenericAction; +export type TodoActionLookup = GenericActionLookup; diff --git a/playground/src/reducers/createReducer.ts b/playground/src/reducers/createReducer.ts index eef8a14..eb195ab 100644 --- a/playground/src/reducers/createReducer.ts +++ b/playground/src/reducers/createReducer.ts @@ -1,9 +1,10 @@ -import { ActionTypes, TodoActionLookup } from '../actions'; +import { ActionTypes, TodoActionLookup, actions } from '../actions'; import { createGenericReducer, HandlerMap, ImmerReducer } from '../redux-utils/reducer'; +import { Reducer } from 'redux'; -export function createReducer( +export function createReducer( initialState: T, - handlerOrMap: HandlerMap | ImmerReducer -) { - return createGenericReducer(initialState, handlerOrMap); + handlerOrMap: HandlerMap | ImmerReducer +): Reducer { + return createGenericReducer(initialState, handlerOrMap); } diff --git a/playground/src/redux-utils/action.ts b/playground/src/redux-utils/action.ts index fd067af..32c96dc 100644 --- a/playground/src/redux-utils/action.ts +++ b/playground/src/redux-utils/action.ts @@ -7,3 +7,8 @@ export function action(type: T, payload: P): ActionWithPayl export function action(type: T, payload?: P) { return { type, ...payload }; } + +export type GenericActionMapping = { [somekey in keyof A]: (...args: any) => Action | ActionWithPayload }; +export type GenericActionTypes> = ReturnType['type']; +export type GenericAction> = ReturnType]>; +export type GenericActionLookup> = { [a in GenericActionTypes]: ReturnType }; diff --git a/playground/src/redux-utils/reducer.ts b/playground/src/redux-utils/reducer.ts index be59494..fa6c4a3 100644 --- a/playground/src/redux-utils/reducer.ts +++ b/playground/src/redux-utils/reducer.ts @@ -1,13 +1,14 @@ import { Reducer } from 'redux'; import { Draft, produce } from 'immer'; +import { GenericActionLookup, GenericActionMapping } from './action'; export type ImmerReducer = (state: Draft, action?: A) => T; -export type HandlerMap = { - [actionType in AT]?: ImmerReducer +export type HandlerMap> = { + [actionType in keyof A]?: ImmerReducer[actionType]> }; -function isHandlerFunction( - handlerOrMap: HandlerMap | ImmerReducer +function isHandlerFunction>( + handlerOrMap: HandlerMap | ImmerReducer ): handlerOrMap is ImmerReducer { if (typeof handlerOrMap === 'function') { return true; @@ -16,15 +17,15 @@ function isHandlerFunction( +export function createGenericReducer, AM = keyof GenericActionMapping>( initialState: T, - handlerOrMap: HandlerMap | ImmerReducer + handlerOrMap: HandlerMap | ImmerReducer[AM]> ): Reducer { - return function reducer(state = initialState, action: Lookup[AT]): T { + return function reducer(state = initialState, action: GenericActionLookup[AM]): T { if (isHandlerFunction(handlerOrMap)) { - return produce(state, draft => handlerOrMap(draft, action as Lookup[AT])); + return produce(state, draft => handlerOrMap(draft, action as GenericActionLookup[AM])); } else if (handlerOrMap.hasOwnProperty(action.type)) { - const handler = (handlerOrMap as any)[action.type] as ImmerReducer; + const handler = (handlerOrMap as any)[action.type] as ImmerReducer[AM]>; return produce(state, draft => handler(draft, action)); } else { return state;