`Property 'ethereum' does not exist on type 'Window & typeof globalThis'` error in React
Asked Answered
S

4

21

I am getting the

Property 'ethereum' does not exist on type 'Window & typeof globalThis'

error in React. This is the line generating the issue:

import { ethers } from 'ethers'

const provider = new ethers.providers.Web3Provider(window.ethereum);

Any idea of what could be happening?

Stapleton answered 2/2, 2022 at 18:50 Comment(0)
R
34

Using any as a type is cheating. Using “any” will just remove the error but it wont show you the available properties.

import { MetaMaskInpageProvider } from "@metamask/providers";

declare global {
  interface Window{
    ethereum?:MetaMaskInpageProvider
  }
}
Rupert answered 2/5, 2022 at 0:13 Comment(3)
In MetaMask's doc, it was mentioned that "other Ethereum-compatible browsers" could also have the Window.ethereum. Perhaps putting type MetaMaskInpageProvider would make it only compatible for MetaMask?Masculine
@TerryWindwalker as far as I know, the only browser that ethereum is injected is Brave browser which is not a commonly used browser yetRupert
There is also a library called @metamask/detect-provider. Maybe the answer can be updated with this as a possible alternative solutionDesex
S
30

Create the react-app-env.d.ts file in the src folder with the following script:

/// <reference types="react-scripts" />

interface Window {
    ethereum: any
}
Stapleton answered 2/2, 2022 at 18:50 Comment(2)
also works for vite-env.d.ts 👍Marsupium
Try to avoid using anyDesex
S
11

In my src/react-app-env.d.ts I am using

/// <reference types="react-scripts" />
import { ExternalProvider } from "@ethersproject/providers";

declare global {
  interface Window {
    ethereum?: ExternalProvider;
  }
}

Notice that @ethersproject/providers is an ethers dependency so you do not need to install it.

Then I also added a src/hooks/useMetaMask.ts file with useMetaMask hook that casts the provider to MetaMask provider type. This can be useful if you need to add MetaMask listeners.

import type { MetaMaskInpageProvider } from "@metamask/providers";

export const useMetaMask = () => {
  const ethereum = global?.window?.ethereum;
  if (!ethereum || !ethereum.isMetaMask) return;
  return ethereum as unknown as MetaMaskInpageProvider;
};
Skepful answered 7/8, 2022 at 17:51 Comment(2)
Just wanted to add to this. If you are using Vite, browse over to src/vite-env.d.ts and add the following (notice the decorator a the first line): ``` /// <reference types="vite/client" /> import { ExternalProvider } from "@ethersproject/providers"; declare global { interface Window { ethereum?: ExternalProvider; } } ```Mccue
Note: You need to have ethers installed for this to work!Mccue
N
0

For my NextJs app, I created a file web3.d.ts in the root with the following code:

import { MetaMaskInpageProvider } from "@metamask/providers";

declare global {
  interface Window {
    ethereum?: MetaMaskInpageProvider;
  }
}

Make sure your tsconfig.json file allows the above file in include.

Northway answered 14/11, 2023 at 12:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.