I am trying to use context in NextJS with typescript. One of the values in my context is a useState set function. Setting the default value of that in the createContext arguments is giving me this error.
Property 'Dispatch' does not exist on type 'typeof import("d:/NextJS/crypto-tracker/node_modules/@types/react/index.d.ts")'
I am getting the same error for SetStateAction if I remove Dispatch. The following is the code in my context file.
"use client";
import React, { createContext, useEffect, useState, Dispatch } from "react";
export const CryptoContext = createContext({
allCoins: [],
currency: { name: "usd", symbol: "$" },
setCurrency: React.Dispatch<
React.SetStateAction<{ name: "usd"; symbol: "$" }>
>,
});
const CryptoContextProvider = ({
children,
}: Readonly<{
children: React.ReactNode;
}>) => {
const [allCoins, setAllCoins] = useState([]);
const [currency, setCurrency] = useState({ name: "usd", symbol: "$" });
const fetchAllCoins = async () => {
const options = {
method: "GET",
headers: {
accept: "application/json",
"x-cg-demo-api-key": "",
},
};
fetch(
`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.name}`,
options
)
.then((res) => res.json())
.then((res) => setAllCoins(res))
.catch((err) => console.error(err));
};
useEffect(() => {
fetchAllCoins();
}, [currency]);
const contextValue = { allCoins, currency, setCurrency };
return (
<CryptoContext.Provider value={contextValue}>
{children}
</CryptoContext.Provider>
);
};
export default CryptoContextProvider;
package.json
{
"name": "crypto-tracker",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "15.1.7",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@types/node": "^20",
"@types/react": "^19.0.10",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "15.1.7",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
I have tried reinstalling react, @types/react and react-dom. I have also tried switching the typescript version to use workspace version but it shows both workspace version and vscode version as 5.7.3. The error is still present.
React.Dispatch refers to a type but you are using it as a value in the CryptoContext variable. Here is an improved version of your code using interfaces and initializing the context with a null value.
import React, {
createContext,
useEffect,
useState,
Dispatch,
SetStateAction,
} from "react";
interface Currency {
name: "usd";
symbol: "$";
}
interface CryptoContext {
allCoins: never[]; // improve type here;
currency: Currency;
setCurrency: Dispatch<SetStateAction<Currency>>;
}
export const CryptoContext = createContext<CryptoContext | null>(null);
const CryptoContextProvider = ({
children,
}: Readonly<{
children: React.ReactNode;
}>) => {
const [allCoins, setAllCoins] = useState([]);
const [currency, setCurrency] = useState<Currency>({
name: "usd",
symbol: "$",
});
const fetchAllCoins = async () => {
const options = {
method: "GET",
headers: {
accept: "application/json",
"x-cg-demo-api-key": "",
},
};
fetch(
`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.name}`,
options
)
.then((res) => res.json())
.then((res) => setAllCoins(res))
.catch((err) => console.error(err));
};
useEffect(() => {
fetchAllCoins();
}, [currency]);
const contextValue = { allCoins, currency, setCurrency };
return (
<CryptoContext.Provider value={contextValue}>
{children}
</CryptoContext.Provider>
);
};
export default CryptoContextProvider;