Search code examples
typescriptscopeexportdeclaration

typescript exports causing "error TS2451: Cannot redeclare block-scoped variable"


After a long gap, I am updating an old typescript project to the modern versions of node et al. After fixing a bunch of linter error, I am getting a strange error:

TSError: ⨯ Unable to compile TypeScript:
src/frames/frame.ts:28:7 - error TS2451: Cannot redeclare block-scoped variable 'frames_1'.

28 const frames_1 = require("../frames");
         ~~~~~~~~

  src/execute/eval-pipe.ts:4:7
    4 const frames_1 = require("../frames");
            ~~~~~~~~
    'frames_1' was also declared here.

This apparently due to the typescript compiler creating non-local variables from different import statements:

= frame.ts

export {}
import * as _ from 'lodash'
import { MetaFrame, NilContext } from '../frames'

= eval-pipe.ts

export {}
import { Context, Frame, NilContext } from '../frames'

How is this possible? I added export {} to each file to ensure everything is module-scoped. Do I need a different configuration?

= tsconfig.json

{
  "compilerOptions": {
    "declaration": false,
    "esModuleInterop": true,
    "lib": ["es6"],
    "module": "commonjs",
    "target": "ESNext",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "outDir": "./lib",
    "preserveConstEnums": true,
    "removeComments": true,
    "skipLibCheck": true,
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "test/**/*-spec.ts"
  ]
}

== UPDATE

If, as suggested, I remove "require": "ts-node/register" from mocha_opts, I instead get the error:

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/ernest/Developer/hclang/node_modules/chalk/source/index.js from /Users/ernest/Developer/hclang/src/execute/hc-eval.ts not supported.
Instead change the require of index.js in /Users/ernest/Developer/hclang/src/execute/hc-eval.ts to a dynamic import() which is available in all CommonJS modules.

Which makes me wonder if this line import chalk from 'chalk' is malformed or not being interpreted correctly.


Solution

  • So, this wasn't the "real" issue. I believe I solved this one by enabling type: module in package.json, but that created a bunch of other (more real) problems that took a long time to (mostly) fix.

    FWIW, here's the final config files I ended up with that solved (those) problems. Oddly, there's a couple test files that still give weird .ts errors, but I can work around those for now.

    package.json (partial)

      "type": "module",
      "directories": {
        "lib": "./lib",
        "src": "./src",
        "test": "./test"
      },
      "files": [
        "lib"
      ],
    

    tsconfig.json

    {
      "compilerOptions": {
        "allowSyntheticDefaultImports": true,
        "outDir": "./lib",
        "rootDir": "./src"
      },
      "include": ["src/**/*"],
      "exclude": ["node_modules"]
    }
    

    .mocharc.json

    {
      "extension": ["ts"],
      "require": "ts-node/register"
    }