Search code examples
reactjstypescriptreduxreact-redux

using 'useSelector' hook with typescript returns this error: Object is type unknown


I'm using redux with typescript in my project. My redux initial state is :

const initailState={
    lots:[],
    isLoading:false,
    error:""
}

All I want to do is to see 'state.lots' when i use console.log in layout component but I see this error:

Object is of type 'unknown'.

Here is my store:

import { shoppingReducers } from "./shopping/shoppingReducer.tsx";
export let store=createStore(shoppingReducers)

export type RootState = ReturnType<typeof store.getState>

And here is layout component:

const Layout = ({children}:{
  children:React.ReactNode
}) => {
const state=useSelector((state) => state.lots)
return (<>
{
console.log(state)
}
</>

And of course I didn't forget to privide store in app component:

import {store} from '../redux/store'
import { Provider } from 'react-redux';
  return(<>
 <Layout>
     
  <Component {...pageProps} />

  </Layout>
</>)

I tried to use another solution: Adding customize selector hook in hooks.ts:

import { TypedUseSelectorHook, useSelector } from 'react-redux'
import type { RootState} from './redux/store'

Then I added this hook to layout components to use:

import { useAppSelector } from '../hooks';
const state=useAppSelector((state) => state.lots)

But I received the same error!

what shall I do now?

Update: Here is the reducer :


interface LotsState {
    lots: string[];
    isLoading: boolean;
    error: string;
  }
export const initailState:LotsState={
    lots:[],
    isLoading:false,
    error:""
}

 export const shoppingReducers=(action:any,state:LotsState=initailState)=>{
       switch (action) {
        //  cases to fetch lots from api :
           case GetLotsRequest:
               return{...initailState,isLoading:true}
               break;
               case GetLotsSuccess:
                return{...initailState,lots:action.payload.lots,isLoading:false}
                break;
                case GetLotsFail:
                    return{...initailState,error:action.payload.error,isLoading:false}
                    break;
       
           default:
               return state
               break;
       }
}

And here is actions file:

export const GetLotsRequest=()=>{
    return {
         type:GET_LOTS_REQUEST
    }
}
export const GetLotsSuccess=(lots:Array<any>)=>{
    return {
         type:GET_LOTS_SUCCESS,
         payload:{lots:lots},
    }
}
export const GetLotsFail=(error:string)=>{
    return {
         type:GET_LOTS_FAIL,
         payload:{error:error}
    }
}

Solution

  • That's silly. But in my case the problem was .tsx suffix in importing :

    import { shoppingReducers } from "./shopping/shoppingReducer.tsx";
    

    I changed it to :

    import { shoppingReducers } from "./shopping/shoppingReducer
    

    and it worked! Of course shoppingReducer file is still have .tsx suffix, But I shouldn't write this when I import!