0

I am creating a Context using useContext with TypeScript. I have a function into seperate file MovieDetailProvider.tsx as wrapper in my App.tsx file.

import { Context, MovieObject } from '../interfaces/interfaces'

export const MovieDetailContext = React.createContext<Context | {}>({})

const MovieDetailProvider: React.FC<React.ReactNode> = ({ children }) => {

    const [movieData, setMovieData] = React.useState<MovieObject | {}>({})

    return (
        <MovieDetailContext.Provider value={{movieData, setMovieData}}>
                {children}
        </MovieDetailContext.Provider>
    )
}

export default MovieDetailProvider

Here is Context and MovieObject Interfaces:

export interface Context {
    movieData: MovieObject,
    setMovieData: (movieData: MovieObject) => void
}

export interface MovieObject {
    loading: boolean,
    error: any,
    data: any
}

Also I have 2 components which are "Consumers" using hooks useContext for exchanging data. But when trying to get context with useContext like this:

import { MovieDetailContext } from './MovieDetailProvider'

const MovieDetail: React.FC = () => {

    const { movieData, setMovieData } = useContext<Context>(MovieDetailContext)
....

and

import { MovieDetailContext } from './MovieDetailProvider'


const MovieList:React.FC = () => {

    const { movieData, setMovieData } = useContext<Context>(MovieDetailContext)
....

I have an error in the same place (MovieDetailContext is underlined) in two files. The error is

TypeScript error in /home/glib/ReactCourse/graphql-project/client/src/components/MovieDetail.tsx(8,61):
Argument of type 'Context<{} | Context>' is not assignable to parameter of type 'Context<Context>'.
  The types of 'Provider.propTypes' are incompatible between these types.
    Type 'WeakValidationMap<ProviderProps<{} | Context>> | undefined' is not assignable to type 'WeakValidationMap<ProviderProps<Context>> | undefined'.
      Type 'WeakValidationMap<ProviderProps<{} | Context>>' is not assignable to type 'WeakValidationMap<ProviderProps<Context>>'.
        Types of property 'value' are incompatible.
          Type 'Validator<{} | Context> | undefined' is not assignable to type 'Validator<Context> | undefined'.
            Type 'Validator<{} | Context>' is not assignable to type 'Validator<Context>'.
              Type '{} | Context' is not assignable to type 'Context'.
                Type '{}' is not assignable to type 'Context'.  TS2345

I dont have much experirnce with Typescript and I dont have an idea how to fix this Context error. If anyone has an advice or solution please help: ) Thanks

P.S. This is my App.tsx file

imports...

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache()
})

const App: React.FC = () => {
  return (
    <ApolloProvider client={client}> 
      <MovieDetailProvider>
        <h1>Your Movie List</h1>
        <MovieList/>
        <AddMovie/>
        <MovieDetail/>
      </MovieDetailProvider>
    </ApolloProvider>


  );
}

export default App;

2 Answers2

2

React.useContext<Context>(MovieDetailContext) expects a parameter of type <Context> but your passing in MovieDetailContext which is of type <Context | {}>

You should remove the empty object from the context type and either set it to undefined or the object with the values set to undefined

 export const MovieDetailContext = React.createContext<Context>(undefined);

Same issue with movieData when passing in the value for the Provider it's expecting MovieObject so you need set the type fro the state to a simple MOvieObject and pass in a MovieObject or undefined for initial value

const [movieData, setMovieData] = React.useState<MovieObject>(undefined)
Moshe Sommers
  • 1,466
  • 7
  • 11
1

You problaly need to adapt the type of your useContext statement to match the type of your createContext statement:

// change from
useContext<Context>(MovieDetailContext)
// to
useContext<Context | {}>(MovieDetailContext)
ysfaran
  • 5,189
  • 3
  • 21
  • 51