Typescript 使用redux thunk键入安全使用调度

Typescript 使用redux thunk键入安全使用调度,typescript,redux,redux-thunk,Typescript,Redux,Redux Thunk,我正在使用redux-thunk来使用异步动作生成器。结果也会返回给相应的调用者 function fetchUserName(userId: number): Promise<string> { return Promise.resolve(`User ${userId}`) } function requestUserName(userId: number) { return (dispatch: Dispatch) => { return fetchUs

我正在使用
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,
      })
    })
  }
}
这正按预期工作,但由于类型无效,TypeScript不会编译它

  • useDispatch
    返回的
    dispatch
    未被识别为返回承诺的函数,因此TypeScript认为
    属性“then”在type上不存在(dispatch:dispatch)=>Promise.
  • 即使承诺会得到承认,承诺也应该正确打印
  • 如何解决这种情况

    我可以在
    useDispatch
    周围创建一个包装器,或者重新定义
    dispatch
    的类型,但我不知道在这种特殊情况下该类型应该是什么样子


    非常感谢您的建议。

    useDispatch
    返回
    Dispatch
    类型,因此您只能使用它发送标准操作。要同时分派thunk操作,请将其类型声明为(from
    redux thunk

    ThunkDispatch
    接收门店状态的类型参数以及您的操作类型。它允许发送一个,这基本上是
    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
      }, []);
      ...
    }
    

    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
      }, []);
      ...
    }
    
    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