reduxjs / redux-toolkit

The official, opinionated, batteries-included toolset for efficient Redux development
https://redux-toolkit.js.org
MIT License
10.72k stars 1.17k forks source link

Typescript: configureStore return type EnhancedStore<any, any, [any]> #1566

Closed syberen closed 2 years ago

syberen commented 3 years ago

I followed the docs to set up a store using configureStore as follows:

import { configureStore } from '@reduxjs/toolkit';

import stepReducer from './step';
import insurerReducer from './insurers';
import insurerPackagesReducer from './insurerPackages';
import resultReducer from './result';

export const store = configureStore({
    reducer: {
        step: stepReducer,
        insurer: insurerReducer,
        insurerPackages: insurerPackagesReducer,
        result: resultReducer,
    },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

It appears that the type of store is inferred to be EnhancedStore<any, any, [any]>. This also causes an error at store.getState:

Property 'getState' does not exist on type 'EnhancedStore<any, any, [any]>'.

Any ideas?

syberen commented 3 years ago

I figured out the issue, but still don't understand why. In my tsconfig.json I had the following setting:

"compilerOptions": {
    "baseUrl": "src"
}

Removing this setting fixed the types.

markerikson commented 3 years ago

Huh, weird. No idea, unfortunately :(

inpendio commented 3 years ago

Same thing here. removing baseUrl does resolve this issue, but introduces a bunch of other issues, so it's not really a solution.

"@reduxjs/toolkit": "^1.6.1",

markerikson commented 3 years ago

@inpendio : we'd really need to see a reproduction of the issue to have any chance to investigate further.

inpendio commented 3 years ago

Ok, I think I know why this is happening. If you name your redux folder redux then you get this error. Probably because RTK exports 'redux' definitions. So, renaming the folder to something like state solves the issue.

basurahan commented 2 years ago

@markerikson here is a reproduction from a snack.expo https://snack.expo.dev/@dev.renz/redux-tookit-sample. Please check out store.ts file

markerikson commented 2 years ago

That's.... really weird.

I have no idea what's going on there, tbh.

@phryneas , any thoughts?

phryneas commented 2 years ago

I looked at it, definitely see that there is a problem but don't have the time to investigate at the moment, sorry!

basurahan commented 2 years ago

I just want to update you guys on what I found out. Short back story when I try some tools that I have not used like redux-toolkit I use snack expo to get a good grasp on how to implement it well before integrating it to my projects. I got stuck with this thread issue on snack expo but when I tried it on my real project workspace react-native cli it works just fine.

Basically when I use createStore on the snack expo the the datatype is different when used in my real workspace see the code below Snack Expo

export const store = configureStore({
  reducer: {},
});

// here is the data type it returns
// const store: EnhancedStore<any, any, [any]>

react-native CLI (Real workspace)

export const store = configureStore({
  reducer: {},
});
// here is the data type it returns
/*
 const store: EnhancedStore<any, AnyAction, [ThunkMiddleware<any, AnyAction, null> | ThunkMiddleware<any, AnyAction, undefined>]>
*/
markerikson commented 2 years ago

Hmm. I just googled for expo snack typescript version, and ran across https://github.com/expo/snack/issues/218 , "Snack not using TypeScript 4 or later".

Perhaps the issue is that the Snack editor doesn't have a recent enough version of TypeScript?

basurahan commented 2 years ago

That might be the problem and therefor not an issue with redux-toolkit thank you

markerikson commented 2 years ago

Another user on Discord reported this, although they also said it "went away after removing RTK and the store+reducer, and recreating them". Their repo: https://github.com/min-tut/mintut-frontend-nextjs

Screenshot of what appears to be the main repro code:

image

(and supposedly "switching between type and interface fixes the issue")

markerikson commented 2 years ago

Good news - I figured out the reason!

And it's not even a bug in Redux Toolkit or Redux.

The symptom is that TS can't find the import type { Store } from 'redux' line in the RTK types.

The cause is that having a folder named redux in your application source code, with an index.ts file inside, causes TS to look there for imports from 'redux', and it can't find the actual Redux library types.

So the real answer here appears to be:

don't put a folder named redux in your application source code!

How you actually structure your folders beyond that is app to you. Personally, I'd recommend doing:

/app
  store.ts
  hooks.ts
/features
  /counter
    counterSlice.ts

but that part's up to you.

But please don't create a folder named redux, because that will break TypeScript usage!

If anyone else sees this happening in a different scenario or setup, please comment, but given that this appears to be the problem I'm going to close this.

Dalcio commented 2 years ago

This error may appear when we set the "baseUrl": "./src" instead of "baseUrl": "." In tsconfig.json or jsconfig.json making TS look for Redux package in our src folder and if find it well attempting to use it instead of the correct package. So, to solve this and keep my folder with the redux name, I had to change the "baseUrl" to "."

radchenk0 commented 2 years ago

@markerikson, thanks for pointing it out! My five cents. For those who still want to keep redux folder in a project - you can just remove index.ts file from the redux folder, so you won't be able to import directly from it, kind of tradeof

jellySWATy commented 2 years ago

Thanks a lot guys. You save me too many hours of googling! I used craco in Create React App for using alias and changed baseUrl to './src', so I met this problem.

Sushant5776 commented 2 years ago

Ok, I think I know why this is happening. If you name your redux folder redux then you get this error. Probably because RTK exports 'redux' definitions. So, renaming the folder to something like state solves the issue.

Thanks a lot! Resolved my problem!

mladentsvetkov commented 1 year ago

I figured out the issue, but still don't understand why. In my tsconfig.json I had the following setting:

"compilerOptions": {
    "baseUrl": "src"
}

Removing this setting fixed the types.

Saved my day! Thanks!

mladentsvetkov commented 1 year ago

This error may appear when we set the "baseUrl": "./src" instead of "baseUrl": "." In tsconfig.json or jsconfig.json making TS look for Redux package in our src folder and if find it well attempting to use it instead of the correct package. So, to solve this and keep my folder with the redux name, I had to change the "baseUrl" to "."

why change the baseUrl to '.'?

romgrk commented 1 year ago

So for the record, I encountered this problem as well, and I was about to give up and just use redux when I noticed that I didn't have redux installed in my dependencies. I installed redux as a dependency and all the typescript problems went away :| The typescript works in mysterious ways.

markerikson commented 1 year ago

@romgrk : you shouldn't have to have redux as a dependency. Redux Toolkit already includes the redux package automatically.

If you remove the separate listing for redux, is there still a copy of Redux installed at all?

romgrk commented 1 year ago

Redux was installed & working at runtime, and it has always worked at runtime.

At compile time, I started having the type error described here after modifying something that I can't remember at the moment. The type error went away by adding redux to the dependencies. This was all compile time.

RGXMG commented 1 year ago

@romgrk : you shouldn't have to have redux as a dependency. Redux Toolkit already includes the redux package automatically.

If you remove the separate listing for redux, is there still a copy of Redux installed at all?

I also encountered this problem, which was also solved by installing redux. I am using pnpm, I think it may be caused by pnpm.

ashsajal1 commented 7 months ago
import { configureStore } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useSelector } from 'react-redux';

const store = configureStore({
  reducer: {
    .......
  },
});

export type RootState = ReturnType<typeof store.getState>;

export default store;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

Now use useAppSelectorinstead of useSelector.

bganeshk commented 2 months ago

store has to be under src/app module