typescript - 如何在 Typescript 中使用 redux-thunk 使用 ThunkAction 正确键入 thunk?
问题描述
我正在尝试redux-thunk
使用 Typescript 输入检查我的代码。
从 Redux 的官方文档:Usage with Redux Thunk中,我们得到了这个例子:
// src/thunks.ts
import { Action } from 'redux'
import { sendMessage } from './store/chat/actions'
import { RootState } from './store'
import { ThunkAction } from 'redux-thunk'
export const thunkSendMessage = (
message: string
): ThunkAction<void, RootState, unknown, Action<string>> => async dispatch => {
const asyncResp = await exampleAPI()
dispatch(
sendMessage({
message,
user: asyncResp,
timestamp: new Date().getTime()
})
)
}
function exampleAPI() {
return Promise.resolve('Async Chat Bot')
}
为了减少重复,您可能希望在商店文件中定义一次可重用的 AppThunk 类型,然后在编写 thunk 时使用该类型:
export type AppThunk<ReturnType = void> = ThunkAction<
ReturnType,
RootState,
unknown,
Action<string>
>
问题
我不完全理解ThunkAction
类型的使用:
ThunkAction<void, RootState, unknown, Action<string>>
有 4 种类型参数,对吧?
第一个-void
这是 thunk 的返回类型,对吧?不应该Promise<void>
,因为它是async
?
第二-RootState
这是完整的状态形状,对吗?我的意思是,这不是一个切片,而是完整的状态。
第三-unknown
这是为什么unknown
?这是什么?
第 4 -Action<string>
这个也不明白。为什么Action<T>
将字符串作为参数?应该总是这样string
吗?为什么?
解决方案
从https://github.com/reduxjs/redux-thunk/blob/d28ab03fd1d2dd1de402928a9589857e97142e09/src/index.d.ts
/**
* A "thunk" action (a callback function that can be dispatched to the Redux
* store.)
*
* Also known as the "thunk inner function", when used with the typical pattern
* of an action creator function that returns a thunk action.
*
* @template TReturnType The return type of the thunk's inner function
* @template TState The redux state
* @template TExtraThunkARg Optional extra argument passed to the inner function
* (if specified when setting up the Thunk middleware)
* @template TBasicAction The (non-thunk) actions that can be dispatched.
*/
export type ThunkAction<
TReturnType,
TState,
TExtraThunkArg,
TBasicAction extends Action
> = (
dispatch: ThunkDispatch<TState, TExtraThunkArg, TBasicAction>,
getState: () => TState,
extraArgument: TExtraThunkArg,
) => TReturnType;
第一个- TReturnType
在这里,我们不关心返回类型——无论如何,我们不等待 thunk 的结果。在 TS 中,可以将任何函数分配给 void 签名,因为它不会损害类型安全。这是一个示例,显示我可以将各种异步/非异步函数分配给 void 函数签名:
我们使用提供的调度函数来触发我们关心的下一个动作 - 所以就时间而言唯一重要的是我们正在等待某些事情的异步函数内部。Redux-thunk 在内部没有对这个函数的结果做任何事情。这是关于 thunk 如何在后台工作的一个很好的解释器(只需要预览):
https://frontendmasters.com/courses/rethinking-async-js/synchronous-and-asynchronous-thunks/
第二- TState 是的 - 这是整个商店状态类型
第三 - TExtraThunkARg 您可以添加您自己的自定义额外参数,该参数在分派和 getState 之后传递到 thunk。这默认为未知,因为除非您明确提供它,否则不清楚它将是什么。这是类型安全的,因为尝试与未知参数交互会导致编译时错误。
更多信息:https ://github.com/reduxjs/redux-thunk#injecting-a-custom-argument
第四——TBasicAction
这是一个动作类型。动作是最基本的动作类型——每个type
属性都是一个纯字符串。或者,您可以提供自己的更具体的类型 - 即type MyActionType = 'FOO_ACTION' | 'BAR_ACTION'
进一步的类型安全/缩小。然后,您将其用作操作。
推荐阅读
- git - 为克隆的存储库安装 requirements.txt 时出现错误消息
- java - 我正在使用 Android Studio 4.1,但我无法解决问题。请看下面的代码
- javascript - 如何使用 HTML 和 CSS 将 div 放在图像上?
- python - Keras:图层顺序的输入0与图层不兼容
- python - Pyinstaller EXE 只能从 CMD 运行,点击 EXE 不起作用
- sql - SQLite3 Order by highest/lowest numerical value
- javascript - 正确地将第二个动态模板添加到 Gatsby/NetlifyCMS - 我哪里出错了?
- java - 如何在部署环境中将 java 应用程序与 3rd 方库链接
- python - 如何解压缩压缩的 base64 字符串?
- f# - 如何在 Elmish 中同时应用硬编码类和方法类?