TypeScript 中的 Redux Thunk
Redux Thunk in TypeScript
我正在尝试更好地了解 ThunkDispatch 函数和 TypeScript。获得了使用 redux 和 thunk 的代码。
// This is redux-thunk source code
import { Middleware, Action, AnyAction } from "redux";
export interface ThunkDispatch<S, E, A extends Action> {
<T extends A>(action: T): T;
<R>(asyncAction: ThunkAction<R, S, E, A>): R;
}
export type ThunkAction<R, S, E, A extends Action> = (
dispatch: ThunkDispatch<S, E, A>,
getState: () => S,
extraArgument: E
) => R;
===================
import { Action } from 'redux'
import { ThunkAction } from 'redux-thunk'
import { ThunkDispatch } from 'redux-thunk'
interface ReduxState {
// redux states
}
type ThunkResult<R> = ThunkAction<R, ReduxState, undefined, Action>
type ReduxDispatch = ThunkDispatch<ReduxState, undefined, Action>
const loadAppData = (): ThunkResult<void> => async (dispatch, getState) => {
// get app data
dispatch(MyAction.getAppDataSuccess(17))
}
const mapDispatchToProps = (dispatch: ReduxDispatch) => ({
loadAppData: () => dispatch(loadAppData()),
})
我目前的理解:
export interface ThunkDispatch<S, E, A extends Action> {
<T extends A>(action: T): T;
<R>(asyncAction: ThunkAction<R, S, E, A>): R;
}
ThunkDispatch
是一个具有 2 个属性的接口,我们称它们为 A 和 B。A 是一个函数,其参数名为 action
,类型为 T
和 return 是 T
类型的东西。类似地,对于 B,它是一个带有 asyncAction
类型的 ThunkAction<R, S, E, A>
参数和 return 类型的 R
.
参数的函数
问题
<T extends A>
和 <R>
部分是否只是暗示一个新的泛型类型?
我目前的理解:
const mapDispatchToProps = (dispatch: ReduxDispatch) => ({
loadAppData: () => dispatch(loadAppData()),
})
dispatch
作为参数是 ReduxDispatch
的一种类型,它是具有 2 个 属性 函数的接口。
loadAppData
是一个将return类型ThunkResult<void>
的函数,相当于ThunkAction<Void, ReduxState, undefined, Action>
。如果我们将这些类型放入 ThunkAction
定义中,它会匹配 async (dispatch, getState) => { ... }
的签名
问题
mapDispatchToProps
中的dispatch(loadAppData())
、loadAppData()
、return是一个ThunkResult<void>
,本质上是一个函数。 dispatch
只是一个带有 2 个 属性 函数的接口,那么这个语法对我来说没有意义,interface(func)
如果我有什么误解,请指出!谢谢
我个人无法在 TS 手册中找到对接口函数重载进行彻底解释的地方。
所有可用的是:
如果你提供的声明我没记错的话
export interface ThunkDispatch<S, E, A extends Action> {
<T extends A>(action: T): T;
<R>(asyncAction: ThunkAction<R, S, E, A>): R;
}
可以以其他方式实现为以下 2 种函数类型的联合:
type ThunkDispatch<S, E, A extends Action> = (<T extends A>(action: T) => T) | (<R>(asyncAction: ThunkAction<R, S, E, A>) => R);
或
type ThunkDispatch<S, E, A extends Action> =
| (<T extends A>(action: T) => T)
| (<R>(asyncAction: ThunkAction<R, S, E, A>) => R);
虽然这是一个迟到的回复,但值得将其作为对这个问题的回答。来自 Redux Usage with Typescript:
Redux Thunk 是一种常用的中间件,用于编写与 Redux 存储交互的同步和异步逻辑。请随时在此处查看其文档。 thunk 是 returns 另一个接受参数 dispatch 和 getState 的函数。 Redux Thunk 有一个内置类型 ThunkAction,我们可以使用它来为这些参数定义类型:
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()
})
)
}
我正在尝试更好地了解 ThunkDispatch 函数和 TypeScript。获得了使用 redux 和 thunk 的代码。
// This is redux-thunk source code
import { Middleware, Action, AnyAction } from "redux";
export interface ThunkDispatch<S, E, A extends Action> {
<T extends A>(action: T): T;
<R>(asyncAction: ThunkAction<R, S, E, A>): R;
}
export type ThunkAction<R, S, E, A extends Action> = (
dispatch: ThunkDispatch<S, E, A>,
getState: () => S,
extraArgument: E
) => R;
===================
import { Action } from 'redux'
import { ThunkAction } from 'redux-thunk'
import { ThunkDispatch } from 'redux-thunk'
interface ReduxState {
// redux states
}
type ThunkResult<R> = ThunkAction<R, ReduxState, undefined, Action>
type ReduxDispatch = ThunkDispatch<ReduxState, undefined, Action>
const loadAppData = (): ThunkResult<void> => async (dispatch, getState) => {
// get app data
dispatch(MyAction.getAppDataSuccess(17))
}
const mapDispatchToProps = (dispatch: ReduxDispatch) => ({
loadAppData: () => dispatch(loadAppData()),
})
我目前的理解:
export interface ThunkDispatch<S, E, A extends Action> {
<T extends A>(action: T): T;
<R>(asyncAction: ThunkAction<R, S, E, A>): R;
}
ThunkDispatch
是一个具有 2 个属性的接口,我们称它们为 A 和 B。A 是一个函数,其参数名为 action
,类型为 T
和 return 是 T
类型的东西。类似地,对于 B,它是一个带有 asyncAction
类型的 ThunkAction<R, S, E, A>
参数和 return 类型的 R
.
问题
<T extends A>
和 <R>
部分是否只是暗示一个新的泛型类型?
我目前的理解:
const mapDispatchToProps = (dispatch: ReduxDispatch) => ({
loadAppData: () => dispatch(loadAppData()),
})
dispatch
作为参数是 ReduxDispatch
的一种类型,它是具有 2 个 属性 函数的接口。
loadAppData
是一个将return类型ThunkResult<void>
的函数,相当于ThunkAction<Void, ReduxState, undefined, Action>
。如果我们将这些类型放入 ThunkAction
定义中,它会匹配 async (dispatch, getState) => { ... }
问题
mapDispatchToProps
中的dispatch(loadAppData())
、loadAppData()
、return是一个ThunkResult<void>
,本质上是一个函数。 dispatch
只是一个带有 2 个 属性 函数的接口,那么这个语法对我来说没有意义,interface(func)
如果我有什么误解,请指出!谢谢
我个人无法在 TS 手册中找到对接口函数重载进行彻底解释的地方。
所有可用的是:
如果你提供的声明我没记错的话
export interface ThunkDispatch<S, E, A extends Action> {
<T extends A>(action: T): T;
<R>(asyncAction: ThunkAction<R, S, E, A>): R;
}
可以以其他方式实现为以下 2 种函数类型的联合:
type ThunkDispatch<S, E, A extends Action> = (<T extends A>(action: T) => T) | (<R>(asyncAction: ThunkAction<R, S, E, A>) => R);
或
type ThunkDispatch<S, E, A extends Action> =
| (<T extends A>(action: T) => T)
| (<R>(asyncAction: ThunkAction<R, S, E, A>) => R);
虽然这是一个迟到的回复,但值得将其作为对这个问题的回答。来自 Redux Usage with Typescript:
Redux Thunk 是一种常用的中间件,用于编写与 Redux 存储交互的同步和异步逻辑。请随时在此处查看其文档。 thunk 是 returns 另一个接受参数 dispatch 和 getState 的函数。 Redux Thunk 有一个内置类型 ThunkAction,我们可以使用它来为这些参数定义类型:
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()
})
)
}