我在输入使用ACTIONS_MAP
调用的函数时遇到了麻烦。我得到了一个"无法调用类型缺少呼号的表达式。"在ACTIONS_MAP[action.type](action);
行。
我认为它发生的是fetchAction
,navigateAction
和openModalAction
各自期望action
参数及其各自的类型。因此,在编译TS时,我不能100%确定我将正确的类型传递给每个动作函数。
import { fetchAction, FetchAction } from './fetch';
import { navigateAction, NavigateAction } from './navigate';
import { openModalAction, OpenModalAction } from './openModal';
const ACTIONS_MAP = {
$fetch: fetchAction,
$navigate: navigateAction,
$openModal: openModalAction,
};
export type Action =
| FetchAction
| NavigateAction
| OpenModalAction;
export function dispatchActions(actions: Action[]) {
actions.forEach(action => {
ACTIONS_MAP[action.type](action);
});
}
有没有办法输入这个或什么是这种方法的好选择?
编辑:
这是fetch.ts
的一个人为设想的例子,其他的是相似的。
export interface FetchAction {
type: '$fetch';
// More types here
}
export function fetchAction(action: FetchAction) {
// Do some work here
}
答案 0 :(得分:2)
在这种情况下避免使用开关的唯一方法(至少我能想到)它使用类型断言。虽然不理想,但有时类型断言在Typescript代码中是必要的,尽管我们应该在绝对必要时使用它们:
type ActionHandler = (a: Action)=> void;
export function dispatchActions(actions: Action[]) {
actions.forEach(action => {
(ACTIONS_MAP[action.type] as ActionHandler)(action);
});
}
答案 1 :(得分:0)
如果您不需要传递对动作函数本身的引用,您可以尝试这样的实际解决方案:
type FooAction = {
type: '$foo';
payload: string;
}
type BlahAction = {
type: '$blah';
payload: number;
}
type Action = FooAction | BlahAction;
function fooAction(action: FooAction) {
console.log(action.payload);
}
function blahAction(action: BlahAction) {
console.log(action.payload + 1)
}
const dispatchAction = (action: Action) => {
switch (action.type) {
case '$foo':
// TS knows action must be a FooAction
return fooAction(action);
case '$blah':
// TS knows action must be a BlahAction
return blahAction(action);
default:
return;
}
}
function dispatchActions(actions: Action[]) {
actions.forEach(action => {
dispatchAction(action);
});
}
dispatchActions([
{ type: "$foo", payload: 'bar' },
{ type: "$blah", payload: 1 }
])
这可以让你在所有正确的地方打字(我认为)。但是,一旦离开每个给定的case
语句,就会丢失缩小信息的类型。因此,您不能只返回该函数,然后再调用它。