Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" on Visual Studio Code

I've been working on unit-testing some code, and out of seemingly nowhere, I got an error about unknown file extensions (before, I got errors about how some type wasn't recognized).

Here is my package.json:

{
  "name": "cgt-core-engine-mv",
  "description": "API container for other CGT plugins",
  "version": "1.01.03",
  "author": "CG-Tespy",
  "repository": {
    "type": "git",
    "url": "https://github.com/CG-Tespy/CGT_CoreEngine_MV"
  },
  "scripts": {
    "build": "tsc & (rollup -c)",
    "test": "mocha -r ts-node/register Test/**/*.ts"
  },
  "dependencies": {},
  "devDependencies": {
    "@types/chai": "^4.2.12",
    "@types/mocha": "^8.0.0",
    "@types/sinon": "^9.0.4",
    "chai": "^4.2.0",
    "mocha": "^8.0.1",
    "rollup": "^2.00.1",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-pluginutils": "^2.8.2",
    "sinon": "^9.0.2",
    "ts-node": "^8.10.2",
    "typescript": "^3.9.6"
  },
  "type": "module"
}

Here is my tsconfig.json:

{
    "compilerOptions": {
      "target": "es5",
      "module": "CommonJS",
      "esModuleInterop": true,

      "sourceMap": false,
      "downlevelIteration": true,
    },
    "include": ["_MainSource/**/*", "Tests/**/*", "@typeDefs/**/*"],
}

I really have no idea where this came from. I have a separate project where I was able to unit-test things just fine, and it didn't give me any errors. The package.json for it:

{
  "name": "unittesting",
  "version": "1.0.0",
  "description": "For practicing unit-testing",
  "main": "main.js",
  "scripts": {
    "test": "mocha -r ts-node/register test/**/*.ts"
    
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/chai": "^4.2.11",
    "@types/mocha": "^8.0.0",
    "chai": "^4.2.0",
    "mocha": "^8.0.1",
    "ts-node": "^8.10.2",
    "typescript": "^3.9.7"
  },
  "type": "module"
}

Its tsconfig:

{
  "compilerOptions": {
    /* Basic Options */

    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "CommonJS",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    
    "esModuleInterop": true,
    
  },
  "include": ["src/**/*", "tests/**/*"],
}

What could be causing this issue? I've tried the suggestions here, but it didn't work (even after looking at the Github issue linked).

like image 451
Tespy Avatar asked Sep 14 '25 03:09

Tespy


2 Answers

The problem is when you are using esm modules (type: module in your package.json file), this is due to the fact that Typescript doesn't touch your import statements at all, (even with the usage of paths aliases), so Typescript tries to protect you, since after transpiling the file, the .ts extension will be remain, which will throw exception at runtime (since ts files are not exists in the dist folder).

You've not encountered this before, probably due to the fact that you are using some bundlers (such as webpack), which changes these imports.

In tests, you are probably transpile it as an separate files.

There are 2 workarounds:

  1. Change all of your import of .ts extensions to .js, (it may break you bundler resolver), this is the one that I'm using, it is really annoying issue.
  2. Run your tests on the bundle
  3. Using some custom made resolvers, such as ts-jest-resolver, if you are using Jest.

Probably the best option would be the 3rd option, but it requires more config.

like image 130
felixmosh Avatar answered Sep 15 '25 16:09

felixmosh


A quick fix would be to add these lines to your tsconfig.json:

{
  "compilerOptions": {
    "noEmit": true,
    "allowImportingTsExtensions": true
  }
}

This won't work if you're using tsc to emit .js or .d.ts files, but if you're using something else for bundling (esbuild, rollup, Babel, or a framework) then this should be fine.

The allowImportingTsExtensions was added in TypeScript 5.0 so make sure you're using 5.0+.

[0] https://www.typescriptlang.org/tsconfig#allowImportingTsExtensions

like image 21
Colin McDonnell Avatar answered Sep 15 '25 17:09

Colin McDonnell