4

I'm new to Typescript and I'm getting the following error on my variable state in using useContext and useReducer hooks:

Type '{ state: {}; dispatch: Dispatch; }' is not assignable to type '{ latlng: null; searchTerm: null; bookingId: null; myPin: null; selectedPin: null; selectedCard: null; selectedCardPin: null; }'.
Object literal may only specify known properties, and 'state' does not exist in type '{ latlng: null; searchTerm: null; bookingId: null; myPin: null; selectedPin: null; selectedCard: null; selectedCardPin: null; }'.ts(2322)

This is my app.tsx:

const App = () => {   
  const initialState = useContext(Context)   
  const [state, dispatch] = useReducer(reducer, initialState)    
  return(
    <Context.Provider value={{ state // <-this is where the error occurs//, dispatch }}>
         ...
    </Context.Provider>    
  )

Following is my context.jsx:

const Context = createContext({
    latlng: null,
    searchTerm: null,
    bookingId: null,
    myPin: null,
    selectedPin: null,
    selectedCard: null, 
    selectedCardPin: null,
})

Revision:

according to the advise, I've changed my `context.tsx' to the following, but still getting the error message:

Argument of type '{ latlng: null; searchTerm: null; bookingId: null; myPin: null; selectedPin: null; selectedCard: null; selectedCardPin: null; }' is not assignable to parameter of type 'MyContextType'.
Object literal may only specify known properties, and 'latlng' does not exist in type 'MyContextType'.ts(2345)

import { createContext } from 'react'

interface MyContextType {
    dispatch: React.Dispatch<any>,
    state: {
      latlng?: any,
      searchTerm?: any,
      bookingId?: any,
      myPin?: any,
      selectedPin?: any,
      selectedCard?: any, 
      selectedCardPin?: any,
    }
}

const Context = createContext<MyContextType>({
    latlng: null,
    searchTerm: null,
    bookingId: null,
    myPin: null,
    selectedPin: null,
    selectedCard: null, 
    selectedCardPin: null,
})

export default Context

2nd revision:

When I change my context.jsx to match the contents of createContext as following:

interface MyContextType {
    latlng?: any,
    searchTerm?: any,
    bookingId?: any,
    myPin?: any,
    selectedPin?: any,
    selectedCard?: any, 
    selectedCardPin?: any,
}

const Context = createContext<MyContextType>({
    latlng: null,
    searchTerm: null,
    bookingId: null,
    myPin: null,
    selectedPin: null,
    selectedCard: null,
    selectedCardPin: null,
})

the error is gone in context.jsx, but it causes a type error in app.jsx.

Type '{ state: {}; dispatch: Dispatch; }' is not assignable to type 'MyContextType'. Object literal may only specify known properties, and 'state' does not exist in type 'MyContextType'.ts(2322)

    <Context.Provider value={{ state //<-- here //, dispatch }}>
    </Context.Provider>

5
  • Declare a type with optional properties like interface MyContextType = { dispatch: Function, state: { latlng?: string, ... } } then use createContext<MyContextType>({ ... }) Commented Aug 7, 2019 at 17:07
  • @p.s.w.g I made the change as you mentioned, but am still getting the error Commented Aug 7, 2019 at 17:31
  • Sorry, for not being more explicit. You'll have to provide the dispatch and wrap state as well to match exactly what you expect to use in<Context.Provider value={}, e.g. createContext<MyContextType>({ dispatch: null, state: { latlng: null, ... }}). Commented Aug 7, 2019 at 17:35
  • @p.s.w.g It seems that if I match the interface to the states in context.jsx, it solves the type error within context.jsx, but it causes an error in app.jsx where state from value doesn't recognize MyContextType Commented Aug 7, 2019 at 18:00
  • Maybe you need interface MyContextType = { dispatch: Dispatch<any>, state: any }? That would sacrifice significant type safety, but it seems like your state object is very loosely defined anyway. Commented Aug 7, 2019 at 18:28

1 Answer 1

2

Add 'as type' when you pass prop to Store.Provider, it can fix this error. Like this:

const [state, dispatch] = React.useReducer(reducer, initialState);
const value = { state, dispatch };
return <Store.Provider value={value as MyContextType}>{props.children}</Store.Provider>;

Let me know if this solves your issue.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.