skip to Main Content

I was trying to pass useState properties through Context.Provider value={{theme, setTheme}} as it was written in tutorial, and after receive it with useContext(Context), but it keeps returning me an error:

const setCurrentUser: any
Property 'setCurrentUser' does not exist on type 'Object'.ts(2339)

Note: This code is fully copied from react docs with little type additions to see if it’s me how’s making such mistake, or I just don’t know how to fix it

I checked usage useContext with TypeScript, but code there is the same as mine and doesn’t provide me an answer

Full code:

import { createContext, useContext, useState, ReactNode, DetailedHTMLProps, ButtonHTMLAttributes, MouseEventHandler } from 'react';

const CurrentUserContext = createContext<Object>({});

export default function MyApp() {
      const [currentUser, setCurrentUser] = useState(null);
      return (
            <CurrentUserContext.Provider
                  value={{
                        currentUser,
                        setCurrentUser
                  }}
            >
                  <Form />
            </CurrentUserContext.Provider>
      );
}

function Form(): JSX.Element {
      return (
            <Panel title="Welcome">
                  <LoginButton />
            </Panel>
      );
}

function LoginButton(): JSX.Element {
      const {
         //////////
         // Error occurs here   

            currentUser,
            setCurrentUser

         //////////
      } = useContext(CurrentUserContext);

      if (currentUser !== null) {
            return <p>You logged in as {currentUser.name}.</p>;
      }

      return (
            <Button onClick={() => {
                  setCurrentUser({ name: 'Advika' })
            }}>Log in as Advika</Button>
      );
}

interface PanelProps {
      title: string
      children: ReactNode
}

function Panel({ title, children }: PanelProps): JSX.Element {
      return (
            <section className="panel">
                  <h1>{title}</h1>
                  {children}
            </section>
      )
}

interface ButtonProps extends DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
      children: ReactNode
      onClick?: MouseEventHandler<HTMLButtonElement>
}

function Button({ children, onClick }: ButtonProps): JSX.Element {
      return (
            <button className="button" onClick={onClick}>
                  {children}
            </button>
      );
}

If this wording of the question is not correct, please let me know

2

Answers


  1. at this line

    const CurrentUserContext = createContext<Object>({});
    

    adding initContextValue

    const initContextValue = {
      currentUser: {name: 'abc'},
      setCurrentUser: ({name: 'abc'}) => {}
    }
    const CurrentUserContext = createContext<Object>(initContextValue);
    

    y will see the TS can work

    Login or Signup to reply.
  2. The type of CurrentUserContext is set to Object (L#3), where it’s supposed to be explicit object structures (or any)

    Take a look at the TS docs on object types

    createContext<{
        currentUser: string, 
        setCurrentUser: fn(_:any) => void 
    }>
    
    

    Should be the approximate type you’re looking for. I have no way to tell for sure.

    But this gets messy, so consider instantiating as suggested by H294. Or using a type alias

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search