TypeScript
Completed
-
Section 1: Getting Started
-
Section 2: Basic Types
-
Section 3: Functions and Objects
-
Section 4: Advanced Types
-
Section 5: Object-Oriented TypeScript
-
Section 6: Working with Modules
-
Section 7: Tooling and Practice
-
Section 8: Type-Level Programming
-
Section 9: TypeScript with Backends
-
Section 10: Testing Typed Code
-
Section 11: Data Validation with Types
-
Section 12: Practical Projects
-
Section 13: Compiler Internals
-
Section 14: Configuration Deep Dive
-
Section 15: Enums, Symbols, and Special Types
-
Section 16: Working with Async Code
-
Section 17: TypeScript and the DOM
-
Section 18: Advanced Generics Practice
-
Section 19: Working with Third-Party Types
-
Section 20: Monorepo and Large-Scale Practices
-
Section 21: Common Pitfalls and Best Practices
-
Section 22: Interview Practice
-
Section 23: Handbook: Narrowing In Depth
-
Section 24: Handbook: Object Types In Depth
-
Section 25: Handbook: Classes In Depth
-
Section 26: Handbook: Modules In Depth
-
Section 27: Handbook: Declaration Files In Depth
-
Section 28: JSX and Namespaces
-
Section 29: Compiler Configuration Reference
-
Section 30: More Practice Exercises
-
Section 31: Handbook: Everyday Types Deep Dive
-
Section 32: Utility Types Full Reference
-
Section 33: Decorators Reference
-
Section 34: Mixins and Advanced OOP Patterns
-
Section 35: Iterators and Generators Typing
-
Section 36: More Type-Level Programming Practice
-
Section 37: TypeScript Ecosystem Tools
-
Section 38: TypeScript with Testing Frameworks
-
Section 39: TypeScript for Library Authors
-
Section 40: More Interview Practice
-
Section 41: Handbook: Functions In Depth
-
Section 42: Handbook: Type Manipulation Deep Dive
-
Section 43: More Real-World Patterns
-
Section 44: TypeScript Release Notes Highlights
-
Section 45: Final Practice and Review
91: Target and Module Settings Explained
I've noticed a recurring pattern when I'm reviewing PRs from developers moving to TypeScript: there is a persistent belief that the target setting in your tsconfig.json is what tells TypeScript which version of the language it should use to validate your code. People often think, "If I set target to ES5, I can't use arrow functions in my source code because ES5 doesn't support them."
That is completely wrong. And it's a distinction that will save you hours of head-scratching if you get it straight now.
"Target" is for the Runtime, Not the Compiler
The TypeScript compiler (tsc) is designed to let you use the latest and greatest ECMAScript features regardless of where your code eventually runs. The target setting doesn't restrict what you can write; it defines what the output looks like.
Let's look at a real example. Suppose you write this modern snippet:
async function getUserData(id: string) {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
If you set "target": "ESNext", the compiled JavaScript will look almost identical to the code above because modern browsers and Node.js versions support async/await natively. But if you change that to "target": "ES5", TypeScript will "downlevel" that code. It will transform that sleek async function into a bulky mess of state machines and helper functions (using __awaiter and __generator) so that it can run in Internet Explorer 11 without crashing.
I'll be honest: downleveling has a cost. It makes your output files larger and slightly slower. My rule of thumb? Set your target to the lowest version of JavaScript that your actual users' browsers (or your server's Node version) can execute.
The "Module" Setting Isn't About Your TS Imports
This is where things get truly confusing. You're already using import and export in your TypeScript files, so you might assume the module setting is just telling TypeScript that you're using modules. It's not.
The module setting tells TypeScript how to rewrite those imports and exports in the generated JavaScript. This is critical because the JavaScript ecosystem is split between different module systems: CommonJS (used by older Node.js) and ESM (the official JavaScript standard used by browsers and newer Node.js).
If you use "module": "CommonJS", your import { User } from './models' becomes const models_1 = require("./models"). If you use "module": "ESNext", it stays as an import statement.
Here is the trap: if you set "module": "ESNext" but try to run that code in a Node.js environment that isn't configured for ESM (missing "type": "module" in package.json), Node will throw a SyntaxError: Unexpected token 'export'. The code is valid JavaScript, but it's the wrong flavor of JavaScript for that specific environment.
Matching Settings to Your Environment
Because target and module are independent, you can mix and match. You might want to target ES6 (to get classes and arrow functions) but use CommonJS modules (because your legacy Node server requires require()).
When I start a new project, I usually follow this logic:
- Building a modern web app (Vite/Webpack): I usually go with
target: "ESNext"andmodule: "ESNext". I let the bundler handle the final compatibility. - Building a Node.js library: I often stick with
module: "CommonJS"to ensure the widest possible compatibility with other npm packages. - Building for legacy browsers:
target: "ES5"is the old reliable, thoughES6is generally safe for almost everything today.
📋 Practical Task
Fixing the 'Unexpected token export' Error in Node.js
You are tasked with fixing a small Node.js utility project. The project is intended to run on an older version of Node.js that only supports CommonJS, but the current TypeScript configuration is outputting ES Modules, causing the app to crash on startup.
The current tsconfig.json:
{
"compilerOptions": {
"target": "ES6",
"module": "ESNext",
"outDir": "./dist",
"strict": true
}
}
The source code (src/index.ts):
export const greet = (name: string) => `Hello, ${name}!`;
console.log(greet("Developer"));
The Goal: Modify the tsconfig.json so that when the code is compiled, the export keyword is converted to module.exports (CommonJS), allowing it to run in the legacy Node environment without changing any of the TypeScript source code.
Instructions:
- Identify which setting is causing the
SyntaxErrorin Node.js. - Update the
tsconfig.jsonto the correct module system. - Explain why changing
targetwouldn't solve this specific "Unexpected token export" issue.
There are no comments for now.