语言与环境
emitDecoratorMetadata
发布版本: 1.5
启用为装饰器输出类型元数据的实验性支持,该功能与 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();Try当 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();
Try当 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();
TryexperimentalDecorators
发布版本: 1.5
启用装饰器的实验性支持,该版本装饰器早于 TC39 标准化进程。
装饰器是一个尚未完全纳入 JavaScript 规范的语言特性。 这意味着 TypeScript 中的实现版本可能与 TC39 最终决定后的 JavaScript 实现有所不同。
你可以在手册中了解有关 TypeScript 装饰器支持的更多信息。
jsx
允许的值:
preserve、react、react-native、react-jsx、react-jsxdev发布版本: 1.6
控制 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]
"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;
TryReact 开发转换:"react-jsxdev"[1]
"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"
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelloWorld = void 0;
const HelloWorld = () => <h1>Hello world</h1>;
exports.HelloWorld = HelloWorld;
TryReact Native:"react-native"
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelloWorld = void 0;
const HelloWorld = () => <h1>Hello world</h1>;
exports.HelloWorld = HelloWorld;
Try传统 React 运行时:"react"
"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"):
/* @jsxRuntime classic */
export const HelloWorld = () => <h1>Hello world</h1>;对该文件始终使用自动运行时("react-jsx"):
/* @jsxRuntime automatic */
export const HelloWorld = () => <h1>Hello world</h1>;jsxFactory
允许的值: 任何标识符或带点的标识符。
默认值:
React.createElement发布版本: 2.2
在使用经典 JSX 运行时编译 JSX 元素时,更改在 .js 文件中调用的函数。 最常见的更改是在使用 preact 时使用 "h" 或 "preact.h" 而不是默认的 "React.createElement"。
例如,此 TSX 文件:
import { h } from "preact";
const HelloWorld = () => <div>Hello</div>;当 jsxFactory: "h" 时看起来像:
"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 */ 指令。
所选的工厂也会影响在回退到全局 JSX 之前查找 JSX 命名空间(用于类型检查信息)的位置。
如果工厂定义为 React.createElement(默认值),编译器将在检查全局 JSX 之前检查 React.JSX。如果工厂定义为 h,它将在检查全局 JSX 之前检查 h.JSX。
jsxFragmentFactory
默认值:
React.Fragment发布版本: 4.0
指定在指定了 jsxFactory 编译器选项以针对 React JSX 输出时要使用的 JSX 片段工厂函数,例如 Fragment。
例如,使用此 TSConfig:
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment"
}
}此 TSX 文件:
import { h, Fragment } from "preact";
const HelloWorld = () => (
<>
<div>Hello</div>
</>
);将看起来像:
"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 */ 指令。
例如:
/** @jsx h */
/** @jsxFrag Fragment */
import { h, Fragment } from "preact";
const HelloWorld = () => (
<>
<div>Hello</div>
</>
);TryjsxImportSource
默认值:
react发布版本: 4.1
相关: jsx、jsxFactory
声明当使用 TypeScript 4.1 中引入的 "react-jsx" 或 "react-jsxdev" 作为 jsx 时,用于导入 jsx 和 jsxs 工厂函数的模块说明符。
借助 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" });
}
Try例如,如果你想使用 "jsxImportSource": "preact",你需要一个类似这样的 tsconfig:
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react-jsx",
"jsxImportSource": "preact",
"types": ["preact"]
}
}这将生成如下代码:
"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或者,你可以使用每个文件的编译指示来设置此选项,例如:
/** @jsxImportSource preact */
export function App() {
return <h1>Hello World</h1>;
}这将为 _jsx 工厂添加 preact/jsx-runtime 作为导入。
注意: 为了使其按预期工作,你的 tsx 文件必须包含 export 或 import,以便被视为一个模块。
lib
TypeScript 包含一组内置 JS API(如 Math)的默认类型定义,以及浏览器环境中存在的内容(如 document)的类型定义。 TypeScript 还包含与指定的 target 相匹配的较新 JS 功能的 API;例如,如果 target 是 ES6 或更高版本,则 Map 的定义可用。
你可能出于以下几个原因想要更改这些:
- 你的程序不在浏览器中运行,因此你不希望包含
"dom"类型定义 - 你的运行时平台提供了某些 JavaScript API 对象(可能通过 polyfill),但尚未支持给定 ECMAScript 版本的完整语法
- 你对某些高级 ECMAScript 版本的部分功能有 polyfill 或原生实现,但不是全部
在 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、类型化数组等 |
ES2018 | ES2018 中可用的其他 API - async 迭代器、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 源代码中查看完整列表。
libReplacement
TypeScript 4.5 引入了用自定义文件替换默认 lib 文件的可能性。 所有内置库文件将首先尝试从名为 @typescript/lib-* 的包中解析。 例如,你可以通过以下 package.json 将 dom 库锁定到 @types/web 包的特定版本:
{
"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
允许的值:
legacy、auto、force默认值: "auto":将具有导入、导出、import.meta、jsx(使用 jsx: react-jsx)或 esm 格式(使用 module: node16+)的文件视为模块。
发布版本: 4.7
此设置控制 TypeScript 如何确定文件是脚本还是模块。
有三种选择:
"auto"(默认)- TypeScript 不仅会查找导入和导出语句,还会在运行module为nodenext或node16时检查package.json中的"type"字段是否设置为"module",并在jsx为react-jsx运行时检查当前文件是否为 JSX 文件。"legacy"- 与 4.6 及更早版本相同的行为,使用导入和导出语句确定文件是否为模块。"force"- 确保每个非声明文件都被视为模块。
noLib
禁用自动包含任何库文件。 如果设置了此选项,lib 将被忽略。
如果没有一组关键原始类型(如 Array、Boolean、Function、IArguments、Number、Object、RegExp 和 String)的接口,TypeScript 无法编译任何内容。如果你使用 noLib,则期望你为这些类型包含自己的类型定义。
reactNamespace
默认值:
React发布版本: 1.8
改用 jsxFactory。为 TSX 文件指定针对 react 目标时调用 createElement 的对象。
target
允许的值:
es3、es5、es6/es2015、es2016、es2017、es2018、es2019、es2020、es2021、es2022、es2023、es2024、es2025、esnext默认值: 如果 module 是
node20,则为es2023;如果 module 是nodenext,则为esnext;否则为ES5。发布版本: 1.0
现代浏览器支持所有 ES6 特性,因此 ES6 是一个不错的选择。 如果你的代码部署在较旧的环境中,你可以选择设置较低的目标;如果你的代码保证在较新的环境中运行,则可以设置较高的目标。
target 设置会更改哪些 JS 特性被降级,哪些保持不变。 例如,如果 target 是 ES5 或更低,箭头函数 () => this 将转换为等效的 function 表达式。
更改 target 也会更改 lib 的默认值。 你可以根据需要“混搭” target 和 lib 设置,但为了方便起见,你可以只设置 target。
对于像 Node 这样的开发者平台,根据平台类型及其版本,存在 target 的基线。你可以在 tsconfig/bases 找到一组社区组织的 TSConfig,其中包含常见平台及其版本的配置。
特殊的 ESNext 值指的是你的 TypeScript 版本支持的最高版本。 应谨慎使用此设置,因为它在不同 TypeScript 版本之间含义不同,并且可能使升级更不可预测。
useDefineForClassFields
此标志用于迁移到即将推出的类字段标准版本。TypeScript 在 TC39 批准之前多年就引入了类字段。即将推出的规范的最新版本具有与 TypeScript 实现不同的运行时行为,但语法相同。
此标志切换到即将推出的 ECMA 运行时行为。
你可以在3.7 发布说明中阅读有关过渡的更多信息。