reactjstypescriptnext.js

Property 'Dispatch' does not exist on type 'typeof import("d:/NextJS/crypto-tracker/node_modules/@types/react/index.d.ts")'


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.


Solution

  • 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;