3815 words
19 minutes
TSConfig 语言和环境配置
2025-02-27 10:11:26
2025-02-27 15:33:13

← 返回 TSConfig 参考指南


生成装饰器元数据 - emitDecoratorMetadata#

启用对装饰器的实验性类型元数据生成支持,该功能与 reflect-metadata 模块配合使用。

例如,以下是 TypeScript 代码:

function LogMethod( target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor ) { console.log(target); console.log(propertyKey); console.log(descriptor); } class Demo { @LogMethod public foo(bar: number) { // do nothing } } const demo = new Demo();

当 emitDecoratorMetadata 未设置为 true(默认值)时,生成的 JavaScript 代码如下:

"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; function LogMethod(target, propertyKey, descriptor) { console.log(target); console.log(propertyKey); console.log(descriptor); } class Demo { foo(bar) { // do nothing } } __decorate([ LogMethod ], Demo.prototype, "foo", null); const demo = new Demo();

当 emitDecoratorMetadata 设置为 true 时,生成的 JavaScript 代码如下:

"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; function LogMethod(target, propertyKey, descriptor) { console.log(target); console.log(propertyKey); console.log(descriptor); } class Demo { foo(bar) { // do nothing } } __decorate([ LogMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Number]), __metadata("design:returntype", void 0) ], Demo.prototype, "foo", null); const demo = new Demo();

相关配置:

  • experimentalDecorators

发布版本:1.5

实验性装饰器 - experimentalDecorators#

启用对装饰器的实验性支持,这是一个早于 TC39 标准化进程的装饰器版本。

装饰器是一个尚未完全纳入 JavaScript 规范的语言特性。这意味着 TypeScript 中的实现版本可能与 TC39 最终确定的 JavaScript 实现有所不同。

你可以在 TypeScript 手册中找到更多关于装饰器支持的信息。

相关配置:

  • emitDecoratorMetadata

发布版本:1.5

JSX - jsx#

控制 JSX 结构在 JavaScript 文件中的生成方式。这个配置只影响以 .tsx 文件为起点生成的 JS 文件的输出。

  • react-jsx:生成 .js 文件时,将 JSX 转换为经过优化的 _jsx 调用,适用于生产环境
  • react-jsxdev:生成 .js 文件时,将 JSX 转换为 _jsx 调用,仅用于开发环境
  • preserve:生成 .jsx 文件时,保持 JSX 不变
  • react-native:生成 .js 文件时,保持 JSX 不变
  • react:生成 .js 文件时,将 JSX 转换为等效的 React.createElement 调用

例如,以下示例代码:

export const HelloWorld = () => <h1>Hello world</h1>;

React:“react-jsx”[1]

import { jsx as _jsx } from "react/jsx-runtime"; export const HelloWorld = () => _jsx("h1", { children: "Hello world" });

React 开发转换:“react-jsxdev”[1]

import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime"; const _jsxFileName = "/home/runner/work/TypeScript-Website/TypeScript-Website/packages/typescriptlang-org/index.tsx"; export const HelloWorld = () => _jsxDEV("h1", { children: "Hello world" }, void 0, false, { fileName: _jsxFileName, lineNumber: 9, columnNumber: 32 }, this);

Preserve:“preserve”

import React from 'react'; export const HelloWorld = () => <h1>Hello world</h1>;

React Native:“react-native”

import React from 'react'; export const HelloWorld = () => <h1>Hello world</h1>;

传统 React 运行时:“react”

import React from 'react'; export const HelloWorld = () => React.createElement("h1", null, "Hello world");

你也可以使用 @jsxRuntime 注释在文件级别上使用此选项。

始终为此文件使用经典运行时(“react”):

/* @jsxRuntime classic */ export const HelloWorld = () => <h1>Hello world</h1>;

始终为此文件使用自动运行时(“react-jsx”):

/* @jsxRuntime automatic */ export const HelloWorld = () => <h1>Hello world</h1>;

允许的值:

  • preserve
  • react
  • react-native
  • react-jsx
  • react-jsxdev

相关配置:

  • jsxFactory
  • jsxFragmentFactory
  • jsxImportSource

发布版本:1.6

JSX 工厂函数 - jsxFactory#

更改使用经典 JSX 运行时编译 JSX 元素时在 .js 文件中调用的函数。最常见的更改是使用 “h” 或 “preact.h” 代替默认的 “React.createElement”(如果使用 Preact)。

例如,这个 TSX 文件:

import { h } from "preact"; const HelloWorld = () => <div>Hello</div>;

使用 jsxFactory: “h” 后的输出如下:

const preact_1 = require("preact"); const HelloWorld = () => (0, preact_1.h)("div", null, "Hello");

你也可以使用类似于 Babel 的 /** @jsx h */ 指令在文件级别上使用此选项:

/** @jsx h */ import { h } from "preact"; // 找不到模块 'preact' 或其对应的类型声明 const HelloWorld = () => <div>Hello</div>;

所选的工厂函数还会影响在回退到全局 JSX 之前查找 JSX 命名空间(用于类型检查信息)的位置。

如果工厂函数被定义为 React.createElement(默认值),编译器将在检查全局 JSX 之前检查 React.JSX。如果工厂函数被定义为 h,它将在检查全局 JSX 之前检查 h.JSX。

默认值:

  • React.createElement

允许的值:

  • 任何标识符或带点的标识符

相关配置:

  • jsx
  • jsxFragmentFactory
  • jsxImportSource

发布版本:2.2

JSX Fragment 工厂函数 - jsxFragmentFactory#

当使用 jsxFactory 编译器选项并以 react JSX 为目标时,指定要使用的 JSX fragment 工厂函数,例如 Fragment。

例如,使用以下 TSConfig:

{ "compilerOptions": { "target": "esnext", "module": "commonjs", "jsx": "react", "jsxFactory": "h", "jsxFragmentFactory": "Fragment" } }

这个 TSX 文件:

import { h, Fragment } from "preact"; const HelloWorld = () => ( <> <div>Hello</div> </> );

会生成如下代码:

const preact_1 = require("preact"); const HelloWorld = () => ((0, preact_1.h)(preact_1.Fragment, null, (0, preact_1.h)("div", null, "Hello")));

你也可以在文件级别上使用这个选项,类似于 Babel 的 /* @jsxFrag h */ 指令。

例如:

/** @jsx h */ /** @jsxFrag Fragment */ import { h, Fragment } from "preact"; // 找不到模块 'preact' 或其对应的类型声明 const HelloWorld = () => ( <> <div>Hello</div> </> );

默认值:

  • React.Fragment

相关配置:

  • jsx
  • jsxFactory
  • jsxImportSource

发布版本:4.0

JSX 导入源 - jsxImportSource#

声明用于导入 jsx 和 jsxs 工厂函数的模块说明符,适用于在 TypeScript 4.1 中引入的 jsx 为 “react-jsx” 或 “react-jsxdev” 的情况。

在 React 17 中,该库通过单独的导入支持新形式的 JSX 转换。

例如,对于以下代码:

import React from "react"; function App() { return <h1>Hello World</h1>; }

使用以下 TSConfig:

{ "compilerOptions": { "target": "esnext", "module": "commonjs", "jsx": "react-jsx" } }

TypeScript 生成的 JavaScript 代码如下:

"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); function App() { return (0, jsx_runtime_1.jsx)("h1", { children: "Hello World" }); }

例如,如果你想使用 “jsxImportSource”: “preact”,你需要一个这样的 tsconfig:

{ "compilerOptions": { "target": "esnext", "module": "commonjs", "jsx": "react-jsx", "jsxImportSource": "preact", "types": ["preact"] } }

这将生成如下代码:

function App() { return (0, jsx_runtime_1.jsx)("h1", { children: "Hello World" }); }

另外,你也可以使用文件级别的 pragma 来设置这个选项,例如:

/** @jsxImportSource preact */ export function App() { return <h1>Hello World</h1>; }

这将添加 preact/jsx-runtime 作为 _jsx 工厂的导入。

注意:为了使其按预期工作,你的 tsx 文件必须包含一个导出或导入,以便它被视为一个模块。

默认值:

  • react

相关配置:

  • jsx
  • jsxFactory

发布版本:4.1

库文件 - lib#

TypeScript 包含一组默认的内置 JS API 类型定义(如 Math),以及浏览器环境中的类型定义(如 document)。TypeScript 还包括与你指定的目标相匹配的较新 JS 特性的 API;例如,如果目标是 ES6 或更新版本,则可以使用 Map 的定义。

你可能出于以下几个原因想要更改这些设置:

  • 你的程序不在浏览器中运行,所以你不想要 “dom” 类型定义
  • 你的运行时平台提供了某些 JavaScript API 对象(可能通过 polyfills),但尚未完全支持给定 ECMAScript 版本的完整语法
  • 你有一些 polyfills 或某些(但不是全部)更高级 ECMAScript 版本的原生实现

在 TypeScript 4.5 中,lib 文件可以被 npm 模块覆盖,你可以在博客中了解更多信息。

高级库

名称内容
ES5所有 ES5 功能的核心定义
ES2015ES2015(也称为 ES6)中可用的其他 API - array.find、Promise、Proxy、Symbol、Map、Set、Reflect 等
ES6”ES2015” 的别名
ES2016ES2016 中可用的其他 API - array.include 等
ES7”ES2016” 的别名
ES2017ES2017 中可用的其他 API - Object.entries、Object.values、Atomics、SharedArrayBuffer、date.formatToParts、typed arrays 等
ES2018ES2018 中可用的其他 API - async iterables、promise.finally、Intl.PluralRules、regexp.groups 等
ES2019ES2019 中可用的其他 API - array.flat、array.flatMap、Object.fromEntries、string.trimStart、string.trimEnd 等
ES2020ES2020 中可用的其他 API - string.matchAll 等
ES2021ES2021 中可用的其他 API - promise.any、string.replaceAll 等
ES2022ES2022 中可用的其他 API - array.at、RegExp.hasIndices 等
ES2023ES2023 中可用的其他 API - array.with、array.findLast、array.findLastIndex、array.toSorted、array.toReversed 等
ESNextESNext 中可用的其他 API - 这会随着 JavaScript 规范的发展而变化
DOMDOM 定义 - window、document 等
WebWorkerWebWorker 上下文中可用的 API
ScriptHostWindows 脚本宿主系统的 API

单独的库组件

名称
DOM.Iterable
ES2015.Core
ES2015.Collection
ES2015.Generator
ES2015.Iterable
ES2015.Promise
ES2015.Proxy
ES2015.Reflect
ES2015.Symbol
ES2015.Symbol.WellKnown
ES2016.Array.Include
ES2017.object
ES2017.Intl
ES2017.SharedMemory
ES2017.String
ES2017.TypedArrays
ES2018.Intl
ES2018.Promise
ES2018.RegExp
ES2019.Array
ES2019.Object
ES2019.String
ES2019.Symbol
ES2020.String
ES2020.Symbol.wellknown
ES2021.Promise
ES2021.String
ES2021.WeakRef
ESNext.AsyncIterable
ESNext.Array
ESNext.Intl
ESNext.Symbol

此列表可能已过时,你可以在 TypeScript 源代码中查看完整列表。

相关配置:

  • noLib

发布版本:2.0

在 React 17 中,该库通过单独的导入支持新形式的 JSX 转换。

例如,对于以下代码:

import React from "react"; function App() { return <h1>Hello World</h1>; }

使用以下 TSConfig:

{ "compilerOptions": { "target": "esnext", "module": "commonjs", "jsx": "react-jsx" } }

TypeScript 生成的 JavaScript 代码如下:

"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); function App() { return (0, jsx_runtime_1.jsx)("h1", { children: "Hello World" }); }

例如,如果你想使用 “jsxImportSource”: “preact”,你需要一个这样的 tsconfig:

{ "compilerOptions": { "target": "esnext", "module": "commonjs", "jsx": "react-jsx", "jsxImportSource": "preact", "types": ["preact"] } }

这将生成如下代码:

function App() { return (0, jsx_runtime_1.jsx)("h1", { children: "Hello World" }); }

另外,你也可以使用文件级别的 pragma 来设置这个选项,例如:

/** @jsxImportSource preact */ export function App() { return <h1>Hello World</h1>; }

这将添加 preact/jsx-runtime 作为 _jsx 工厂的导入。

注意:为了使其按预期工作,你的 tsx 文件必须包含一个导出或导入,以便它被视为一个模块。

默认值:

  • react

相关配置:

  • jsx
  • jsxFactory

发布版本:4.1

模块检测 - moduleDetection#

此设置控制 TypeScript 如何判断一个文件是脚本还是模块。

有三个选项:

  • “auto”(默认值)- TypeScript 不仅会查找 import 和 export 语句,还会在使用 module: nodenext 或 node16 时检查 package.json 中的 “type” 字段是否设置为 “module”,并在使用 jsx: react-jsx 时检查当前文件是否为 JSX 文件。

  • “legacy” - 与 4.6 及之前版本相同的行为,使用 import 和 export 语句来判断文件是否为模块。

  • “force” - 确保每个非声明文件都被视为模块。

默认值:

  • “auto”:将具有 imports、exports、import.meta、jsx(使用 jsx: react-jsx)或 esm 格式(使用 module: node16+)的文件视为模块。

允许的值:

  • legacy
  • auto
  • force

发布版本:4.7

不包含库文件 - noLib#

禁用自动包含任何库文件。如果设置了此选项,lib 选项将被忽略。

如果没有一组关键原语的接口(如:Array、Boolean、Function、IArguments、Number、Object、RegExp 和 String),TypeScript 将无法编译任何内容。如果你使用 noLib,你需要自己提供这些类型定义。

相关配置:

  • lib

发布版本:1.0

React 命名空间 - reactNamespace#

请使用 jsxFactory 代替。用于指定在针对 react 的 TSX 文件中调用 createElement 时使用的对象。

默认值:

  • React

发布版本:1.8

目标版本 - target#

现代浏览器支持所有 ES6 特性,因此 ES6 是一个不错的选择。如果你的代码需要部署到较旧的环境中,你可能会选择设置一个较低的目标版本;如果你的代码保证在较新的环境中运行,则可以设置一个较高的目标版本。

target 设置会改变哪些 JS 特性被降级处理,哪些保持不变。例如,如果 target 是 ES5 或更低版本,箭头函数 () => this 将被转换为等效的函数表达式。

更改 target 也会改变 lib 的默认值。你可以根据需要”混合搭配” target 和 lib 设置,但为了方便起见,你可以只设置 target。

对于 Node 等开发平台,target 的基准取决于平台的类型和版本。你可以在 tsconfig/bases 找到一组社区组织的 TSConfig,其中包含常见平台及其版本的配置。

特殊值 ESNext 指的是你的 TypeScript 版本支持的最高版本。使用此设置时应谨慎,因为它在不同的 TypeScript 版本之间的含义不同,可能会使升级变得不太可预测。

默认值:

  • ES5

允许的值:

  • es3
  • es5
  • es6/es2015
  • es2016
  • es2017
  • es2018
  • es2019
  • es2020
  • es2021
  • es2022
  • es2023
  • es2024
  • esnext

发布版本:1.0

使用 Define 定义类字段 - useDefineForClassFields#

此标志用于迁移到即将推出的类字段标准版本。TypeScript 在 TC39 批准之前多年就引入了类字段。即将发布的规范的最新版本具有与 TypeScript 实现不同的运行时行为,但语法相同。

此标志切换到即将推出的 ECMA 运行时行为。

你可以在 3.7 版本的发布说明中阅读更多关于此转换的信息。

默认值:

  • 如果 target 是 ES2022 或更高版本(包括 ESNext),则为 true;否则为 false。

发布版本:3.7

模块检测 - moduleDetection#

此设置控制 TypeScript 如何判断一个文件是脚本还是模块。

有三个选项:

  • “auto”(默认值)- TypeScript 不仅会查找 import 和 export 语句,还会在使用 module: nodenext 或 node16 时检查 package.json 中的 “type” 字段是否设置为 “module”,并在使用 jsx: react-jsx 时检查当前文件是否为 JSX 文件。

  • “legacy” - 与 4.6 及之前版本相同的行为,使用 import 和 export 语句来判断文件是否为模块。

  • “force” - 确保每个非声明文件都被视为模块。

默认值:

  • “auto”:将具有 imports、exports、import.meta、jsx(使用 jsx: react-jsx)或 esm 格式(使用 module: node16+)的文件视为模块。

允许的值:

  • legacy
  • auto
  • force

发布版本:4.7

不包含库文件 - noLib#

禁用自动包含任何库文件。如果设置了此选项,lib 选项将被忽略。

如果没有一组关键原语的接口(如:Array、Boolean、Function、IArguments、Number、Object、RegExp 和 String),TypeScript 将无法编译任何内容。如果你使用 noLib,你需要自己提供这些类型定义。

相关配置:

  • lib

发布版本:1.0

React 命名空间 - reactNamespace#

请使用 jsxFactory 代替。用于指定在针对 react 的 TSX 文件中调用 createElement 时使用的对象。

默认值:

  • React

发布版本:1.8

目标版本 - target#

现代浏览器支持所有 ES6 特性,因此 ES6 是一个不错的选择。如果你的代码需要部署到较旧的环境中,你可能会选择设置一个较低的目标版本;如果你的代码保证在较新的环境中运行,则可以设置一个较高的目标版本。

target 设置会改变哪些 JS 特性被降级处理,哪些保持不变。例如,如果 target 是 ES5 或更低版本,箭头函数 () => this 将被转换为等效的函数表达式。

更改 target 也会改变 lib 的默认值。你可以根据需要”混合搭配” target 和 lib 设置,但为了方便起见,你可以只设置 target。

对于 Node 等开发平台,target 的基准取决于平台的类型和版本。你可以在 tsconfig/bases 找到一组社区组织的 TSConfig,其中包含常见平台及其版本的配置。

特殊值 ESNext 指的是你的 TypeScript 版本支持的最高版本。使用此设置时应谨慎,因为它在不同的 TypeScript 版本之间的含义不同,可能会使升级变得不太可预测。

默认值:

  • ES5

允许的值:

  • es3
  • es5
  • es6/es2015
  • es2016
  • es2017
  • es2018
  • es2019
  • es2020
  • es2021
  • es2022
  • es2023
  • es2024
  • esnext

发布版本:1.0

使用 Define 定义类字段 - useDefineForClassFields#

此标志用于迁移到即将推出的类字段标准版本。TypeScript 在 TC39 批准之前多年就引入了类字段。即将发布的规范的最新版本具有与 TypeScript 实现不同的运行时行为,但语法相同。

此标志切换到即将推出的 ECMA 运行时行为。

你可以在 3.7 版本的发布说明中阅读更多关于此转换的信息。

默认值:

  • 如果 target 是 ES2022 或更高版本(包括 ESNext),则为 true;否则为 false。

发布版本:3.7

TSConfig 语言和环境配置
https://0bipinnata0.my/posts/typescript/tsconfig/08-language-and-environment/
Author
0bipinnata0
Published at
2025-02-27 10:11:26