1

I have:

export interface AppStateType {
    isOnline: boolean
}

const AppContext = createContext([{}, () => { }]);

const AppProvider = (props) => {
    const [appState, setAppState] = useState<AppStateType>({
        isOnline: true
    })

    return <AppContext.Provider value={[appState, setAppState]}>
        {props.children}
    </AppContext.Provider>
}
export { AppContext, AppProvider }

When when I try to use it:

const [appState, setAppState] = useContext<AppStateType>(AppContext)

I get a Typescript error:

Argument of type 'Context<{}[]>' is not assignable to parameter of type 'Context<AppStateType>'.
  The types of 'Provider.propTypes.value' are incompatible between these types.
    Type 'Validator<{}[]>' is not assignable to type 'Validator<AppStateType>'.
      Type '{}[]' is not assignable to type 'AppStateType'.
1
  • This answer probably will help you - it is the same constellation. Commented May 13, 2020 at 13:20

2 Answers 2

1

The reason you get this error is because the return type of Context is not an AppStateType but an array with two values. First is AppState and second is a dispatcher

With typescript you can type the context when its created like

const AppContext = createContext<[AppStateType, React.Dispatch<any>]>(null);

Post this, you can simply use it like

const [appState, setAppState] = useContext(AppContext);

Sample Demo

NOTE: Define the default value to createContext as null since it would only be used when there is no provider in the hierarchy tree. In which case it mostly might be an error

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

4 Comments

What error does it throw, because it compiles well for me if I create context like const AppContext = createContext<[AppStateType, React.Dispatch<any>]>(null); Make sure you pass null to createContext as arguments because that will only be used if no PRovider is available in the hierachy which means your code is incorrect so it better throw an error than go unnoticed
yeah, passing null instead of [] is an option. But it depends on the environment - it is only possible with strict mode / strictNullChecks option disabled, which is the case in the sandbox (you can try adding "strictNullChecks": true to tsconfig.json).
Hmm, it still works even if I add strictNullChecks in TS config
Here is a copy of your sandbox, where those checks are activated.
0

The parameter for createContext is the default value of the context see here So if your context type is the state and set state like so

[AppStateType,React.Dispatch<React.SetStateAction<AppStateType>>]

You need to give a default value

const AppContext = createContext([{}, () => { }]);

Should be

const AppContext = createContext<[AppStateType,React.Dispatch<React.SetStateAction<AppStateType>>]>([{isOnline:false},()=> false]);

2 Comments

Then I can't set the appState
@Shamoon You're right I updated my answer to have an array of State and sSetState as type for context allowing the array to be passed as the value

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.