[Ethereum] TypeError: web3_1.default is not a constructor

npmtypescriptweb3js

I'm trying to convert a DApp that uses web3.js from JavaScript to TypeScript, but I have encountered a bunch of runtime errors. I'm using Visual Studio Code IDE, and I'm compiling to ES6. I've reduced the project to the smallest code that still has these problems.

Can someone help me fix this? Thanks in advance!

(if I forgot to include some important information, please feel free to comment)

NPM packages:

  • @types/web3 (version 1.0.12)

  • web3 (version 1.0.0-beta.36)

Web page:

<script src="system.js"></script>
<script>
System.config({
    baseURL: './out',
    packages: {
        './out': {
            defaultJSExtensions: 'js'
        }
    },
    meta: {
        '*': {
            format: 'register'
        }
    },
});
window.addEventListener("load", (async function(){
    await System.import("init");
}));
</script>

Init.ts:

import Web3 from "web3";

const ABI: any[] = [];
let web3: Web3;
export async function init()
{
    if (typeof (window as any).web3 !== "undefined")
    {
        const injectedWeb3: Web3 = ((window as any).web3 as Web3);
        web3 = new Web3(injectedWeb3.currentProvider); // This line produces the error: TypeError: web3_1.default is not a constructor
    }
    else
    {
        web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
    }
    const myABIinstance = new web3.eth.Contract(ABI);
}
init();

The full stack trace of the run-time error:

TypeError: web3_1.default is not a constructor
init.ts:10
    at /home/jesse/MinimalWeb3Typescript/init.ts:10:16
    at Generator.next (<anonymous>)
    at /home/jesse/MinimalWeb3Typescript/out/init.js:8:76
    at new Promise (<anonymous>)
    at __awaiter (/home/jesse/MinimalWeb3Typescript/out/init.js:4:17)
    at init (/home/jesse/MinimalWeb3Typescript/out/init.js:14:17)
    at Object.execute (/home/jesse/MinimalWeb3Typescript/init.ts:18:1)
    at U (/home/jesse/MinimalWeb3Typescript/system.js:4:8818)
    at /home/jesse/MinimalWeb3Typescript/system.js:4:11430
    at /home/jesse/MinimalWeb3Typescript/system.js:4:11499

Best Answer

If using a recent web3 (e.g. 1.0.0-beta.50), a possible remedy is to set esModuleInterop:

{
  "compilerOptions": {
    "esModuleInterop": true
  }
}

See also: https://github.com/ethereum-ts/TypeChain/blob/5b4f397c64b7d32cdf2ce50062f69bad324efa99/test/integration/targets/web3-1.0.0/