流式安全操作



我正在使用流,我想让我的减速器更安全。我发现这条评论提出了一个解决方案,我觉得这个解决方案很好,很适合我的代码库:https://github.com/reduxjs/redux/issues/992#issuecomment-191152574

我正试图使用%checks关键字将其移植到流中,但它不起作用。

我的代码:

export type Action<T> = {
type: string,
payload: T,
};
interface ActionCreator<P> {
type: string;
(payload: P): Action<P>;
}
export function actionCreator<P>(type: string): ActionCreator<P> {
return Object.assign((payload: P) => ({ type, payload }), { type });
}
export function isActionOfType<P>(
action: Action<any>,
creator: ActionCreator<P>
): boolean %checks {
return action.type === creator.type;
}

每当我在类似的减速器功能中使用它时

(...)
case isActionOfType(action, getArticles):
// action.payload is still any
(...)

我做错什么了吗?有可能让这个打字脚本解决方案在流中工作吗?或者我应该使用不同的方法?如果是,你有什么建议?

在TypeScript中,您不会使用case语句,而是使用if语句。

在Redux中没有必须使用case语句的规则,事实上,我们不再鼓励在TypeScript中使用这种模式,而是支持带有类型保护的if语句。

所以我想你可以试试。很抱歉,我不能在流方面真正帮助你,我只能就如何推荐TypeScript的现代模式给出一般建议,并希望这些模式能反映在流中。

一般来说,您还可以查看官方的Redux工具包,它带来了所有这些抽象。它只是部分流类型的,但这些类型可能已经满足了您的需求,或者您甚至可以改进它们。

如果您构建了一个类型泛型,该泛型具有一个与有效负载类型链接的类型字符串引用,则可以使用切换用例。我不知道像你这样的用例是否可行,因为如果条件是针对case中的strings而不是booleans进行测试,那么切换用例几乎是它们自己的。

下面的解决方案利用了类型细化,因此基于您编写的条件JS,流将推断有效负载结构。这里需要注意的是,在action参数中,您必须添加所有可能的类型有效载荷,否则flow不知道可以从哪些结构进行细化,这可以在其他地方进行分解,但这也有助于锁定减速器中的变化,以防您不想处理的情况。

试流

type AppT = {}
type ActionT<T, P> = {|
type: T,
payload: P,
|};
type PayloadA = {| a: string |};
type PayloadB = {| b: string |};
const initialState = {};
const reducer = (
state: AppT = initialState,
action: ActionT<'ACTION_A', PayloadA> | ActionT<'ACTION_B', PayloadB>,
): AppT => {
switch (action.type) {
case 'ACTION_A': {
return {
...state,
a: action.payload.a,
};
}
case 'ACTION_B': {
return {
...state,
a: action.payload.a, // <-- it fails because type refines to PayloadB
b: action.payload.b,
};
}
default:
return state;
}
};

最新更新