Introduction: "Your .ts file won't open? You're not alone"
\n\nImagine: you're writing awesome TypeScript code, save the file with the .ts extension, run the command node myfile.ts... and get something like this in response: "Unknown file extension ".ts". Sound familiar? If you've looked on Stack Overflow, you know this question has gathered thousands of views and hundreds of comments. The problem is old, but still relevant.
In this article, we won't just copy an answer from a forum. We'll break down why this happens, how to fix it, and what to do to never encounter this error again. You'll learn how to properly configure a TypeScript project, use ts-node and the tsconfig.json configuration. Let's go!
Why does the "Unknown file extension ".ts"" error occur?
\n\nLet's get straight to the point. Node.js does not understand .ts files by default. It only knows .js, .json, .mjs, and .cjs. When you write node myfile.ts, Node.js honestly tries to execute the TypeScript code as regular JavaScript, but encounters syntax it doesn't recognize (for example, types, interfaces, generics).
The result is an error. But there's another scenario: you're using ts-node or tsx, but still see the same message. Why? Because in modern versions of Node.js (starting from version 16), strict extension checking was added in package.json, especially when "type": "module" is set.
Main causes:
\n- \n
- Direct execution of
node file.ts— Node.js cannot compile TypeScript on the fly. \n - Missing
ts-nodeortsx— no tool for transpilation. \n - Incorrect
tsconfig.jsonconfiguration — for example, module or target not specified. \n - Issues with
package.json— if"type": "module"is set,ts-nodemay require explicit extension specification. \n
Solution 1: Using ts-node (classic method)
\n\nThe simplest way to run TypeScript without prior compilation is to use ts-node. This package compiles .ts files in memory and passes the result to Node.js.
Installation and execution
\nnpm install -g ts-node\nts-node myfile.ts\n\nIf you're using a local project, it's better to install it as a dev dependency:
\nnpm install --save-dev ts-node\nnpx ts-node myfile.ts\n\nExample of a simple hello.ts file:
const greet = (name: string): string => {\n return `Hello, ${name}!`;\n};\n\nconsole.log(greet("World"));\n\nRun it: npx ts-node hello.ts — and you'll see "Hello, World!" in the console. It works!
But there's a catch: "type": "module"
\nIf your package.json has "type": "module", ts-node may refuse to work. In this case, you can either temporarily remove this line or use the --esm flag:
npx ts-node --esm myfile.ts\n\nSolution 2: Using tsx (modern tool)
\n\ntsx is a faster alternative to ts-node, based on esbuild. It works with ESM out of the box and doesn't require additional flags.
Installation:
\nnpm install --save-dev tsx\n\nExecution:
\nnpx tsx myfile.ts\n\nExample using modern TypeScript features:
\n// types.ts\nexport interface User {\n id: number;\n name: string;\n email: string;\n}\n\nconst user