问题
I'm having issues adding a property when I create a new Redux Store in Typescript:
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
with the following error message:
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 | }
Any suggestions?
回答1:
@types/
| - redux.d.ts
src/
| ...
| ... store.ts
in redux.d.ts
import * as Redux from "redux"
declare module "redux" {
export interface Store {
sagaTask: ... // provide the types for `store.sagaTask` here
}
}
in store.ts
const store = createStore(...)
store.sagaTask = ...
this is known as declaration merging / module augmentation.
You need to also setup your tsconfig.json
to read types from this @types
dir. Add "typeRoots": [ "./@types", "./node_modules/@types" ]
to this file (note: these are relative to your baseDir
, so modify accordingly.
Also note that you're creating a contract between your types and the code you write. If you fail to setup your middleware properly, sagaTask
will be Required
in types but undefined
in reality.
回答2:
I haven't used Saga so I'm not sure about best practices or what ramifications this approach might have, but the issue is that the Store type doesn't have a sagaTask, so TypeScript won't let this happen. The easiest way that I can see to solve this is to extend Store and add a sagaTask field, then copy the old store to a new object of the extended type.
The downside to this is that you could easily run into a situation where a function is expecting an object with a Store type, so it won't accept this new object.
Are you sure this needs to be a property of the store, or can you just run sagaMiddleware.run(rootSaga)?
来源:https://stackoverflow.com/questions/57649207/adding-properties-to-created-redux-store-in-typescript