【问题标题】:Adding properties to created Redux Store in Typescript在 Typescript 中向创建的 Redux Store 添加属性
【发布时间】:2019-12-30 03:09:24
【问题描述】:

我在 Typescript 中创建新的 Redux Store 时添加属性时遇到问题:

const bindMiddleware = middleware => {
  if (process.env.NODE_ENV !== 'production') {
    const { composeWithDevTools } = require('redux-devtools-extension')
    return composeWithDevTools(applyMiddleware(...middleware))
  }
  return applyMiddleware(...middleware)
}

function configureStore (initialState = exampleInitialState) {
  const sagaMiddleware = createSagaMiddleware()
  const store = createStore(
    rootReducer,
    initialState,
    bindMiddleware([sagaMiddleware])
  )

  store.sagaTask = sagaMiddleware.run(rootSaga)

  return store
}

export default configureStore

带有以下错误消息:

27:9 Property 'sagaTask' does not exist on type 'Store<{ error: any; count: number; lastUpdate: number; light: boolean; placeholderData: any; } | { lastUpdate: any; light: boolean; count: number; error: boolean; placeholderData: any; }, any>'.
    25 |   )
    26 | 
  > 27 |   store.sagaTask = sagaMiddleware.run(rootSaga)
       |         ^
    28 | 
    29 |   return store
    30 | }

有什么建议吗?

【问题讨论】:

  • TypeScript 的想法是,您在编译时就知道每个 Object 将具有哪些属性,因此您必须在使用它们之前定义这些属性。 store 已经在某处有一个 TypeScript 定义,该定义没有提及任何关于 sagaTask 的内容。

标签: javascript reactjs typescript redux redux-saga


【解决方案1】:
@types/
| - redux.d.ts
src/
| ...
| ... store.ts

redux.d.ts

import * as Redux from "redux"

declare module "redux" {
  export interface Store {
    sagaTask: ... // provide the types for `store.sagaTask` here 
  }
}

store.ts

const store = createStore(...)
store.sagaTask = ...

这被称为declaration merging / module augmentation

您还需要设置您的tsconfig.json 以从此@types 目录中读取类型。将"typeRoots": [ "./@types", "./node_modules/@types" ] 添加到该文件中(注意:这些是相对于您的baseDir,因此请进行相应修改。

还请注意,您正在创建类型和您编写的代码之间的契约。如果您未能正确设置中间件,sagaTask 的类型将是 Required,但实际上是 undefined

【讨论】:

    【解决方案2】:

    我没有使用过 Saga,所以我不确定最佳实践或这种方法可能产生的后果,但问题是 Store 类型没有 sagaTask,因此 TypeScript 不会让这种情况发生。我可以看到解决此问题的最简单方法是扩展 Store 并添加一个 sagaTask 字段,然后将旧存储复制到扩展类型的新对象。

    这样做的缺点是您很容易遇到这样的情况:函数需要一个具有 Store 类型的对象,因此它不会接受这个新对象。

    您确定这需要是 store 的属性,还是可以只运行 sagaMiddleware.run(rootSaga)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-28
      • 2016-05-30
      • 2016-06-23
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      相关资源
      最近更新 更多