typescript - 类型安全的 useDispatch 和 redux-thunk
问题描述
我正在redux-thunk
使用异步操作创建器。结果也返回给各自的调用者。
function fetchUserName(userId: number): Promise<string> {
return Promise.resolve(`User ${userId}`)
}
function requestUserName(userId: number) {
return (dispatch: Dispatch) => {
return fetchUserName(userId).then(name => {
dispatch({
type: 'SET_USERNAME',
payload: name,
})
})
}
}
这样,存储被更新,同时允许组件直接处理响应。
function User() {
const dispatch = useDispatch()
useEffect(() => {
dispatch(requestUserName(1))
.then(name => {
console.log(`user name is ${name}`)
})
.catch(reason => {
alert('failed fetching user name')
})
}, [])
}
这按预期工作,但由于类型无效,TypeScript 不会对其进行编译。
dispatch
返回的 by不useDispatch
被识别为返回 Promise 的函数,因此 TypeScript 认为Property 'then' does not exist on type '(dispatch: Dispatch<AnyAction>) => Promise<void>'.
.- 即使它会被识别出来,Promise 也应该被正确输入
这种情况如何解决?
对我来说,创建一个包装器useDispatch
或重新定义类型会非常好,dispatch
但我不知道在这种特殊情况下该类型应该是什么样子。
非常感谢您的任何建议。
解决方案
useDispatch
返回Redux 使用Dispatch
的类型,因此您只能使用它调度标准操作。要同时调度 thunk 操作,请将其类型声明为(from )。ThunkDispatch
redux-thunk
ThunkDispatch
接收存储状态、额外的 thunk 参数和您的操作类型的类型参数。它允许调度 a ThunkAction
,这基本上是 的内部函数requestUserName
。
例如,您可以这样键入:
import { ThunkDispatch } from "redux-thunk";
import { AnyAction } from "redux";
type State = { a: string }; // your state type
type AppDispatch = ThunkDispatch<State, any, AnyAction>;
// or restrict to specific actions instead of AnyAction
function User() {
const dispatch: AppDispatch = useDispatch();
useEffect(() => {
dispatch(requestUserName(1))
.then(...) // works now
}, []);
...
}
AppDispatch
也可以从商店推断typeof store.dispatch
:
import thunk, { ThunkDispatch, ThunkMiddleware } from "redux-thunk";
const mw: ThunkMiddleware<State, AnyAction> = thunk;
const dummyReducer = (s: State | undefined, a: AnyAction) => ({} as State);
const store = createStore(dummyReducer, applyMiddleware(mw));
type AppDispatch = typeof store.dispatch // <-- get the type from store
另请参阅 redux 关于使用带有钩子的 typescript 的文档:https ://redux.js.org/usage/usage-with-typescript#define-typed-hooks
推荐阅读
- c - *ip 和 ip 是一回事吗?
- c# - 抛出异常时测试通过
- python - 在 python 中创建填充图像
- java - OpenAPI Generator - Java 11 Native HTTP Client 模板:如何添加自定义标头
- python - 重写解析器函数以启用矢量化
- plugins - Windows 10 命令行上无法识别“raco”
- python - 如何使用协方差矩阵计算 sigma_1 和 sigma_2
- winapi - Direct3D 中的 COM 对象
- mysql - 根据节点服务器上的查询结果触发代码执行
- java - java正则表达式屏蔽列表中的所有元素,最后4个字符可见