【发布时间】:2019-01-06 00:05:03
【问题描述】:
所以我在 todomvc 中有这个经典的 switch case redux reducer,我想使其功能化,但似乎无法为此考虑 ts 类型。
Switch case 非常适合模式匹配,并按类型缩小动作区分联合。但我似乎不知道如何使用功能方法传递缩小的操作,其中对象文字的键应该进行类型缩小。
到目前为止,我得到的是所有函数的联合类型和一些 ts 错误。非常感谢您对此事的任何帮助,以更好地了解如何在 ts 中使用严格类型。
import { action as actionCreator } from 'typesafe-actions';
import uuid from 'uuid';
import { ITodo } from 'types/models';
const ADD_TODO = 'todos/ADD_TODO';
const TOGGLE_ALL = 'todos/TOGGLE_ALL';
const REMOVE_TODO = 'todos/REMOVE_TODO';
export const addTodo = (title: string) => actionCreator(ADD_TODO, { title });
export const removeTodo = (id: string) => actionCreator(REMOVE_TODO, { id });
export const toggleAll = (checked: boolean) =>
actionCreator(TOGGLE_ALL, { checked });
type TodosAction =
| ReturnType<typeof addTodo>
| ReturnType<typeof removeTodo>
| ReturnType<typeof toggleAll>;
type TodosState = ReadonlyArray<ITodo>;
// no idea what typings should be
const switchCase = <C>(cases: C) => <D extends (...args: any[]) => any>(
defaultCase: D
) => <K extends keyof C>(key: K): C[K] | D => {
return Object.prototype.hasOwnProperty(key) ? cases[key] : defaultCase;
};
export default function(
state: TodosState = [],
action: TodosAction
): TodosState {
// union type of 4 functions
const reducer = switchCase({
// (parameter) payload: any
// How do I get types for these?
[ADD_TODO]: payload => [
...state,
{
completed: false,
id: uuid.v4(),
title: payload.title,
},
],
[REMOVE_TODO]: payload => state.filter(todo => todo.id !== payload.id),
[TOGGLE_ALL]: payload =>
state.map(todo => ({
...todo,
completed: payload.checked,
})),
})(() => state)(action.type);
// [ts] Cannot invoke an expression whose type lacks a call signature. Type
// '((payload: any) => { completed: boolean; id: string; title: any; }[]) |
// ((payload: any) => ITodo[...' has no compatible call signatures.
return reducer(action.payload);
}
【问题讨论】:
标签: typescript redux functional-programming switch-statement