生成装饰器元数据 - 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 功能的核心定义 |
ES2015 | ES2015(也称为 ES6)中可用的其他 API - array.find、Promise、Proxy、Symbol、Map、Set、Reflect 等 |
ES6 | ”ES2015” 的别名 |
ES2016 | ES2016 中可用的其他 API - array.include 等 |
ES7 | ”ES2016” 的别名 |
ES2017 | ES2017 中可用的其他 API - Object.entries、Object.values、Atomics、SharedArrayBuffer、date.formatToParts、typed arrays 等 |
ES2018 | ES2018 中可用的其他 API - async iterables、promise.finally、Intl.PluralRules、regexp.groups 等 |
ES2019 | ES2019 中可用的其他 API - array.flat、array.flatMap、Object.fromEntries、string.trimStart、string.trimEnd 等 |
ES2020 | ES2020 中可用的其他 API - string.matchAll 等 |
ES2021 | ES2021 中可用的其他 API - promise.any、string.replaceAll 等 |
ES2022 | ES2022 中可用的其他 API - array.at、RegExp.hasIndices 等 |
ES2023 | ES2023 中可用的其他 API - array.with、array.findLast、array.findLastIndex、array.toSorted、array.toReversed 等 |
ESNext | ESNext 中可用的其他 API - 这会随着 JavaScript 规范的发展而变化 |
DOM | DOM 定义 - window、document 等 |
WebWorker | WebWorker 上下文中可用的 API |
ScriptHost | Windows 脚本宿主系统的 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