【TypeScript】关于设置文件tsconfig.json

2025-02-10T12:03:37+08:00 | 6分钟阅读 | 更新于 2025-02-10T12:03:37+08:00

Macro Zhao

【TypeScript】关于设置文件tsconfig.json

@TOC

推荐超级课程:

target

  • 指定输出JavaScript的版本
  • 默认为 ES5
  • 适当设置可以
    • 缩短编译时间
    • 提高运行时的执行效率
    • 强化开发时的类型检查

target选项各自的差异

比较不同target选项的输出代码

  • TypeScript代码(原始代码)
const fetchData = async (url: string): Promise<{ data: string }> => {
  const response = await fetch(url);
  return { data: await response.text() };
};
  • JavaScript代码(输出代码) target: "ES5"的情况下
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var fetchData = function (url) {
    return __awaiter(this, void 0, void 0, function () {
        var response, text;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    return [4 /*yield*/, fetch(url)];
                case 1:
                    response = _a.sent();
                    return [4 /*yield*/, response.text()];
                case 2:
                    text = _a.sent();
                    return [2 /*return*/, { data: text }];
            }
        });
    });
};

target: "ES2015"的情况下

const fetchData = async (url) => {
  const response = await fetch(url);
  return { data: await response.text() };
};

target: "ES5" → async/await被转换为基于Promise的代码
target: "ES2015" → async/await可以直接使用 → 编译到ES2015时,

  • 代码量减少,输出文件大小变小 → 编译时间缩短
  • 可以利用最新语法,JIT编译器的优化更容易生效 → 运行时执行效率提高

target选项各自的lib差异

改变target时,类型检查使用的lib的默认值也会改变。
target: "ES5"的情况下,lib的默认值为lib: ["es5", "dom", "dom.iterable"]
→ Promise不在lib中,因此以下代码会出现类型错误

const promise: Promise<string> = new Promise(resolve => resolve("Hello")); // 错误: 找不到名称'Promise'。

target为"ES2015"的情况下,lib的默认值为lib: ["es2015", "dom", "dom.iterable"]
→ Promise包含在es2015中,因此不会出现类型错误

选择最合适的target

根据输出JavaScript代码的运行环境选择

  • 在浏览器上运行的情况下
    • 与支持的最旧浏览器版本相匹配
    • 例如: Chrome最新版 / Safari最新版 / Firefox最新版 → target: "ES2022"(参考兼容表
  • 在Node.js上运行的情况下

lib

  • 指定类型检查时引用的标准库
  • 根据target设置lib的默认值,但显式设置lib可以选择适合环境的类型定义

lib选项各自的差异

"target": "ES2022",
"lib": ["ES2022"] // "target": "ES2022"时的默认值

的情况下,ES2022中不包含fetch,因此以下代码会出现类型错误

fetch("https://example.com"); // 找不到名称'fetch'。

使用浏览器API(如fetch或document等)时,需要向lib添加DOM

"target": "ES2022",
"lib": ["ES2022", "DOM"]

选择最合适的lib

根据输出JavaScript代码的运行环境进行选择

  • 在浏览器上运行的情况下

    • 为了能够使用fetch和document的类型,需要设置"DOM"或"DOM.Iterable"。
    • 例如:
    "target": "ES2022",
    "lib": ["ES2022", "dom", "dom.iterable"]
    
  • 在Node.js上运行的情况下

    • 即使target为"ES2022",也应尽量选择"ES2024"等以适应最新的JavaScript规范。
      • “ESNext"可以始终反映最新的JavaScript规范,但由于TypeScript的更新可能会带来意外的变化,因此最好避免使用。
      • “ES2024"被指定时,后续的API在类型检查上可以被使用,因此为了防止运行时错误,需要确认并必要时引入polyfill。
    • 例如:
    "target": "ES2022",
    "lib": ["ES2024"]
    

module

  • 指定输出JavaScript代码的模块系统
  • 默认值
    • target: "ES5" 的情况下 → CommonJS
    • 其他情况 → ES6
  • 如果不适当设置,可能会在环境之间引起import/require的兼容性错误
    • ESModules环境下使用require → SyntaxError: Cannot use require in ES module scope
    • CommonJS环境下使用import → SyntaxError: Cannot use import statement outside a module

module选项各自的差异

  • TypeScript代码(原始代码)
// module.ts
export function greet(name: string) {
  return `Hello, ${name}!`;
}
// index.ts
import { greet } from "./module";
console.log(greet("Alice"));
  • JavaScript代码(输出代码) "module": "CommonJS" 的情况下
// module.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.greet = void 0;
function greet(name) {
  return `Hello, ${name}!`;
}
exports.greet = greet;
// index.js
"use strict";
const { greet } = require("./module");
console.log(greet("Alice"));

"module": "esnext"/"nodenext" 的情况下

// module.js
export function greet(name) {
  return `Hello, ${name}!`;
}
// index.js
import { greet } from "./module.js";
console.log(greet("Alice"));

选择最合适的module

  • 选择"esnext"/"nodenext"(JavaScript代码以ESM方式输出)
    • 使用ESM可以更有效地重用和管理代码
  • 在浏览器上运行的情况下 → esnext
    • 使用最新的ECMAScript特性,可以直接在现代浏览器中使用import/export
  • 在Node.js上运行的情况下 → nodenext
    • Node.js可以同时使用ESM和CommonJS两种模块形式,因此可以根据需要处理这两种格式

moduleResolution

  • 指定在编译时如何按照特定文件类型进行查找的顺序
  • 默认值
    • module: "node16"/"nodenext" 的情况下 → "node16"/"nodenext"
    • 其他情况 → node
  • 如果不适当设置,可能会导致文件或类型无法正确找到,从而在构建或运行时发生错误
    • Cannot find module 'xxx'
    • Cannot find module 'xxx' or its corresponding type declarations.
    • TypeError: xxx is not a function

moduleResolution选项各自的差异

TypeScript代码(原始代码)

/project
  ├── src/
  │   ├── index.ts
  │   ├── utils.ts
  ├── node_modules/
  │   ├── some-package/
  │   │   ├── package.json
  │   │   ├── index.js
  │   │   ├── index.mjs
  │   │   ├── index.cjs

src/utils.ts

export const helper = () => console.log("Helper function");

node_modules/some-package/package.json

{
  "main": "./index.js",
  "exports": {
    "import": "./index.mjs",
    "require": "./index.cjs"
  }
}

选择最合适的moduleResolution

根据输出的JavaScript代码的运行环境进行选择

  • 在浏览器上运行的情况下(使用Vite、Webpack等打包工具) → bundler → 打包工具会处理ESM和CommonJS的差异
  • 在Node.js上运行的情况下 → node16nodenext → 可以同时处理ESM和CommonJS

总结

输出的JavaScript代码如果是

  • 在浏览器上运行的情况下
{
  "target": "ES2023", // 主要针对最新的主流浏览器(如Chrome、Edge、Firefox、Safari等)
  "lib": ["ES2023", "DOM", "DOM.Iterable"], // 可以引用浏览器API的类型
  "module": "esnext", // 使用最新的模块系统
  "moduleResolution": "bundler" // 采用针对打包工具优化的模块解析方式
}
  • 在Node.js上运行的情况下
{
  "target": "ES2023", // 针对Node.js 22版本
  "lib": ["ES2024"], // 可以引用ES2024标准库的类型
  "module": "nodenext", // 使用Node.js支持ESM和CJS的模块系统
  "moduleResolution": "nodenext" // 采用Node.js的模块解析方式
}

© 2011 - 2025 Macro Zhao的分享站

关于我

如遇到加载502错误,请尝试刷新😄

Hi,欢迎访问 Macro Zhao 的博客。Macro Zhao(或 Macro)是我在互联网上经常使用的名字。

我是一个热衷于技术探索和分享的IT工程师,在这里我会记录分享一些关于技术、工作和生活上的事情。

我的CSDN博客:
https://macro-zhao.blog.csdn.net/

欢迎你通过评论或者邮件与我交流。
Mail Me

推荐好玩(You'll Like)
  • AI 动·画
    • 这是一款有趣·免费的能让您画的画中的角色动起来的AI工具。
    • 支持几十种动作生成。
我的项目(My Projects)
  • 爱学习网

  • 小乙日语App

    • 这是一个帮助日语学习者学习日语的App。
      (当然初衷也是为了自用😄)
    • 界面干净,简洁,漂亮!
    • 其中包含 N1 + N2 的全部单词和语法。
    • 不需注册,更不需要订阅!完全免费!
  • 小乙日文阅读器

    • 词汇不够?照样能读日语名著!
    • 越读积累越多,积跬步致千里!
    • 哪里不会点哪里!妈妈再也不担心我读不了原版读物了!
赞助我(Sponsor Me)

如果你喜欢我的作品或者发现它们对你有所帮助,可以考虑给我买一杯咖啡 ☕️。这将激励我在未来创作和分享更多的项目和技术。🦾

👉 请我喝一杯咖啡

If you like my works or find them helpful, please consider buying me a cup of coffee ☕️. It inspires me to create and share more projects in the future. 🦾

👉 Buy me a coffee