TypeScript指定target为ES2018却生成旧版JS代码问题求助
你看到的编译结果其实是符合ES2018标准的,并不是ES5版本,原因如下:
1. 模块系统设置导致的"旧代码"错觉
你在tsconfig.json里设置了"module": "CommonJS",TypeScript会生成CommonJS模块格式的代码——也就是你看到的require、Object.defineProperty(exports, "__esModule", { value: true })这些内容。这是模块加载机制的选择,和target指定的语法版本无关。如果想要生成ES模块(import/export),可以把module改为"ES2018"或"ESNext",前提是你的运行环境支持ES模块。
2. ES2018语法无需降级
你的TypeScript代码里用到的箭头函数、模板字符串、let声明、Map对象这些特性,在ES2018里已经是标准语法,TypeScript不需要将它们转成ES5的写法。对比生成的JS代码:
- 箭头函数
(val, key) => console.log(...)保留了,没有被转成function(val, key) {...} - 模板字符串
Message: ${msg}也保留了,没有变成"Message: " + msg let声明没有被替换成var
这些都证明target: "ES2018"已经生效了——TypeScript只会降级目标版本不支持的语法,ES2018支持的语法会直接保留。
3. lib选项的作用误解
lib选项是用来指定编译时可以使用的标准库类型定义(比如DOM API、ES2018的内置对象类型),它不会影响代码的语法降级逻辑,所以修改lib不会改变编译后的代码版本。
验证方法
你可以尝试写一段ES2018特有的语法,比如异步迭代器for await...of,或者Promise.finally(),编译后会发现这些语法被保留了;如果把target改成ES5,它们会被转成ES5兼容的代码,这样就能直观看到target的作用。
相关代码参考:
index.ts
import { sum } from "./calc"; function printMessage(msg: string): void { console.log(`Message: ${msg}`); } printMessage("Hello, TypeScript developer Raki Lachraf"); printMessage("It is sunny today"); let data = new Map(); data.set("Bob", "London"); data.set("Alice", "Paris"); data.forEach((val, key) => console.log(`${key} lives in ${val}`)); let total = sum(100, 200, 300); console.log(`Total: ${total}`);
calc.ts
export function sum(...vals: number[]): number { return vals.reduce((total, val) => (total += val)); }
tsconfig.json
{ "compilerOptions": { "target": "ES2018", "outDir": "./dist", "rootDir": "./src", "noEmitOnError": true, "module": "CommonJS", "lib": ["ES2018", "DOM"] } }
生成的index.js
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const calc_1 = require("./calc"); function printMessage(msg) { console.log(`Message: ${msg}`); } printMessage("Hello, TypeScript developer Raki Lachraf"); printMessage("It is sunny today"); let data = new Map(); data.set("Bob", "London"); data.set("Alice", "Paris"); data.forEach((val, key) => console.log(`${key} lives in ${val}`)); let total = calc_1.sum(100, 200, 300); console.log(`Total: ${total}`);
package.json
{ "name": "tools", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "tsc-watch --onsuccess \"node dist/index.js\"", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "tsc-watch": "^4.2.9", "typescript": "^4.2.2" } }
内容的提问来源于stack exchange,提问作者Raki Lachraf

