Max Travis
Max Travis

Reputation: 1328

Redux - createStore. Argument of type is not assignable to parameter of type 'DeepPartial<any>'

When I start compilation I always gets a stack error. Which says that my initialState in store is broken or someone else. Moreover, my app is compile normally if I just cut off initialState prop from store, but it's not a good solutions.

I also admit that it's work normally on .js file version of the app. Seem like redux have some problems with the TypeScript.

Error:

TS2345: Argument of type '{ titleSwitch: string; }' is not assignable to parameter of type 'DeepPartial'. Property 'titleSwitch' is incompatible with index signature. Type 'string' is not assignable to type 'DeepPartial'.

My part of code:

import { createStore } from 'redux'
import reducer from './reducers'

const initialState = {
  titleSwitch: false
}

const store = () => {
  return createStore(
    reducer,
    initialState // TS Error
  )
}

Tested on:

"redux": "^4.0.0",
"typescript": "^3.1.1",
"webpack": "^4.16.5"

Upvotes: 3

Views: 12305

Answers (3)

Lin
Lin

Reputation: 1111

It's because of type mismatch, probably between a reducer and an initialState.

For me it was because I used too general interface for action in reducer:

interface FluxStandardAction {
  type: string
  payload?: any
  error?: boolean
  meta?: any
}

So reducer return value action.payload was of type any when it must've been of type string

See https://redux.js.org/recipes/usage-with-typescript

Upvotes: 2

flq
flq

Reputation: 22859

I think Ceciles answer is a good one. I would just like to add that the DeepPartial type is kind of a recursive Partial which works really well when you use multiple reducers combined with combineReducers. Your case is basically too trivial for a typical redux state because the leafs of the state are not objects that can be „Partial“ised.

So yeah, for this playground case TS doesn’t provide much value. Once your state and reducers get more complex, type checking should work pretty well again and you can remove the any-cast.

Upvotes: 4

Cecile
Cecile

Reputation: 1765

If the code works in JS but fails only because of typing in TypeScript, I'd suggest you to use "any" to ignore it:

const store = () =>
  createStore(
    reducer,
    initialState as any
  )

Now you're going to ask me: but why??? What is all the point of TypeScript if you just bypass problems whenever you like.

The reason for that is that if you are doing this for work, you need to consider the value of fighting with the type system all the time:

  • Either it helps you avoiding mistaking, making development easier, that's the real motivation for strict typing
  • Either it plays against you, preventing you doing something legal in JS, it won't make your code more robust because the code in question is something you never really touch (in other words: if using the right typing doesn't change anything in the outcome)

TypeScript has been invented with flexibility in mind and that makes its true power when interoperating with JS libraries. Using perfect and strict typing everywhere makes sense only with languages that have been designed that way from the beginning and this is not the case for JS.

Now don't get me wrong. I'm pretty sure there is a solution to your problem. My reasoning is more about: do you actually need to solve it? Will it brings something useful to your application? Sometimes it doesn't worth it.

Upvotes: 16

Related Questions