Skip to content
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

语言与环境

emitDecoratorMetadata

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

例如,以下是 TypeScript 代码:

ts
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
();
Try

emitDecoratorMetadata 未设置为 true(默认)时,输出的 JavaScript 为:

ts
"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();
Try

emitDecoratorMetadata 设置为 true 时,输出的 JavaScript 为:

ts
"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();
Try

experimentalDecorators

启用装饰器的实验性支持,该版本装饰器早于 TC39 标准化进程。

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

你可以在手册中了解有关 TypeScript 装饰器支持的更多信息。

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 调用

例如

示例代码:

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

React:"react-jsx"[1]

tsx
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelloWorld = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const HelloWorld = () => (0, jsx_runtime_1.jsx)("h1", { children: "Hello world" });
exports.HelloWorld = HelloWorld;
Try

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

tsx
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelloWorld = void 0;
const jsx_dev_runtime_1 = require("react/jsx-dev-runtime");
const _jsxFileName = "/home/runner/work/ts-website/ts-website/index.tsx";
const HelloWorld = () => (0, jsx_dev_runtime_1.jsxDEV)("h1", { children: "Hello world" }, void 0, false, { fileName: _jsxFileName, lineNumber: 7, columnNumber: 32 }, this);
exports.HelloWorld = HelloWorld;
Try

保留:"preserve"

tsx
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelloWorld = void 0;
const HelloWorld = () => <h1>Hello world</h1>;
exports.HelloWorld = HelloWorld;
Try

React Native:"react-native"

tsx
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelloWorld = void 0;
const HelloWorld = () => <h1>Hello world</h1>;
exports.HelloWorld = HelloWorld;
Try

传统 React 运行时:"react"

tsx
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelloWorld = void 0;
const HelloWorld = () => React.createElement("h1", null, "Hello world");
exports.HelloWorld = HelloWorld;
Try

此选项也可以使用 @jsxRuntime 注释在每个文件的基础上使用。

对该文件始终使用经典运行时("react"):

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

对该文件始终使用自动运行时("react-jsx"):

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

jsxFactory

在使用经典 JSX 运行时编译 JSX 元素时,更改在 .js 文件中调用的函数。 最常见的更改是在使用 preact 时使用 "h""preact.h" 而不是默认的 "React.createElement"

例如,此 TSX 文件:

tsx
import { h } from "preact";

const HelloWorld = () => <div>Hello</div>;

jsxFactory: "h" 时看起来像:

tsx
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const preact_1 = require("preact");
const HelloWorld = () => (0, preact_1.h)("div", null, "Hello");
Try

此选项也可以在每个文件的基础上使用,类似于 Babel 的 /** @jsx h */ 指令

tsx
/** @jsx h */
import { 
h
} from "preact";
const
HelloWorld
= () => <
div
>Hello</
div
>;
Try

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

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

jsxFragmentFactory

指定在指定了 jsxFactory 编译器选项以针对 React JSX 输出时要使用的 JSX 片段工厂函数,例如 Fragment

例如,使用此 TSConfig:

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

此 TSX 文件:

tsx
import { h, Fragment } from "preact";

const HelloWorld = () => (
  <>
    <div>Hello</div>
  </>
);

将看起来像:

tsx
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const preact_1 = require("preact");
const HelloWorld = () => ((0, preact_1.h)(preact_1.Fragment, null,
    (0, preact_1.h)("div", null, "Hello")));
Try

此选项也可以在每个文件的基础上使用,类似于 Babel 的 /* @jsxFrag h */ 指令

例如:

tsx
/** @jsx h */
/** @jsxFrag Fragment */

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

jsxImportSource

声明当使用 TypeScript 4.1 中引入的 "react-jsx""react-jsxdev" 作为 jsx 时,用于导入 jsxjsxs 工厂函数的模块说明符。

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

例如,使用此代码:

tsx
import React from "react";

function App() {
  return <h1>Hello World</h1>;
}

使用此 TSConfig:

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

TypeScript 输出的 JavaScript 是:

tsx
"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" });
}
Try

例如,如果你想使用 "jsxImportSource": "preact",你需要一个类似这样的 tsconfig:

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

这将生成如下代码:

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

或者,你可以使用每个文件的编译指示来设置此选项,例如:

tsx
/** @jsxImportSource preact */

export function App() {
  return <h1>Hello World</h1>;
}

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

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

lib

TypeScript 包含一组内置 JS API(如 Math)的默认类型定义,以及浏览器环境中存在的内容(如 document)的类型定义。 TypeScript 还包含与指定的 target 相匹配的较新 JS 功能的 API;例如,如果 targetES6 或更高版本,则 Map 的定义可用。

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

  • 你的程序不在浏览器中运行,因此你不希望包含 "dom" 类型定义
  • 你的运行时平台提供了某些 JavaScript API 对象(可能通过 polyfill),但尚未支持给定 ECMAScript 版本的完整语法
  • 你对某些高级 ECMAScript 版本的部分功能有 polyfill 或原生实现,但不是全部

在 TypeScript 4.5 中,lib 文件可以被 npm 模块覆盖,更多信息请参见博客

高级库

名称内容
ES5所有 ES5 功能的核心定义
ES2015ES2015(也称为 ES6)中可用的其他 API - array.findPromiseProxySymbolMapSetReflect
ES6“ES2015” 的别名
ES2016ES2016 中可用的其他 API - array.include
ES7“ES2016” 的别名
ES2017ES2017 中可用的其他 API - Object.entriesObject.valuesAtomicsSharedArrayBufferdate.formatToParts、类型化数组等
ES2018ES2018 中可用的其他 API - async 迭代器、promise.finallyIntl.PluralRulesregexp.groups
ES2019ES2019 中可用的其他 API - array.flatarray.flatMapObject.fromEntriesstring.trimStartstring.trimEnd
ES2020ES2020 中可用的其他 API - string.matchAll
ES2021ES2021 中可用的其他 API - promise.anystring.replaceAll
ES2022ES2022 中可用的其他 API - array.atRegExp.hasIndices
ES2023ES2023 中可用的其他 API - array.witharray.findLastarray.findLastIndexarray.toSortedarray.toReversed
ESNextESNext 中可用的其他 API - 此列表随 JavaScript 规范的发展而变化
DOMDOM 定义 - windowdocument
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 源代码中查看完整列表。

libReplacement

TypeScript 4.5 引入了用自定义文件替换默认 lib 文件的可能性。 所有内置库文件将首先尝试从名为 @typescript/lib-* 的包中解析。 例如,你可以通过以下 package.jsondom 库锁定到 @types/web的特定版本:

json
{
    "devDependencies": {
       "@typescript/lib-dom": "npm:@types/web@0.0.199"
     }
}

安装后,应存在一个名为 @typescript/lib-dom 的包,TypeScript 将在搜索 lib.dom.d.ts 时始终查找该位置。

--libReplacement 标志允许你禁用此行为。 如果你不使用任何 @typescript/lib-* 包,现在可以使用 --libReplacement false 禁用这些包查找。 将来,--libReplacement false 可能成为默认值,因此如果你当前依赖此行为,应考虑使用 --libReplacement true 显式启用它。

moduleDetection

  • 允许的值: legacyautoforce

  • 默认值: "auto":将具有导入、导出、import.meta、jsx(使用 jsx: react-jsx)或 esm 格式(使用 module: node16+)的文件视为模块。

  • 发布版本: 4.7

此设置控制 TypeScript 如何确定文件是脚本还是模块

有三种选择:

  • "auto"(默认)- TypeScript 不仅会查找导入和导出语句,还会在运行 modulenodenextnode16 时检查 package.json 中的 "type" 字段是否设置为 "module",并在 jsxreact-jsx 运行时检查当前文件是否为 JSX 文件。

  • "legacy" - 与 4.6 及更早版本相同的行为,使用导入和导出语句确定文件是否为模块。

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

noLib

  • 发布版本: 1.0

  • 相关: lib

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

如果没有一组关键原始类型(如 ArrayBooleanFunctionIArgumentsNumberObjectRegExpString)的接口,TypeScript 无法编译任何内容。如果你使用 noLib,则期望你为这些类型包含自己的类型定义。

reactNamespace

  • 默认值: React

  • 发布版本: 1.8

改用 jsxFactory。为 TSX 文件指定针对 react 目标时调用 createElement 的对象。

target

  • 允许的值: es3es5es6/es2015es2016es2017es2018es2019es2020es2021es2022es2023es2024es2025esnext

  • 默认值: 如果 modulenode20,则为 es2023;如果 modulenodenext,则为 esnext;否则为 ES5

  • 发布版本: 1.0

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

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

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

对于像 Node 这样的开发者平台,根据平台类型及其版本,存在 target 的基线。你可以在 tsconfig/bases 找到一组社区组织的 TSConfig,其中包含常见平台及其版本的配置。

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

useDefineForClassFields

  • 默认值: 如果 targetES2022 或更高版本(包括 ESNext),则为 true;否则为 false

  • 发布版本: 3.7

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

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

你可以在3.7 发布说明中阅读有关过渡的更多信息。