Language and Environment
emitDecoratorMetadata
Released: 1.5
Related: experimentalDecorators
Enables experimental support for emitting type metadata for decorators which works with the module reflect-metadata.
For example, here is the 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();TryWith emitDecoratorMetadata not set to true (default) the emitted JavaScript is:
"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();
TryWith emitDecoratorMetadata set to true the emitted JavaScript is:
"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
Released: 1.5
Related: emitDecoratorMetadata
Enables experimental support for decorators, which is a version of decorators that predates the TC39 standardization process.
Decorators are a language feature which hasn't yet been fully ratified into the JavaScript specification. This means that the implementation version in TypeScript may differ from the implementation in JavaScript when it is decided by TC39.
You can find out more about decorator support in TypeScript in the handbook.
jsx
Allowed:
preserve,react,react-native,react-jsx,react-jsxdevReleased: 1.6
Related: jsxFactory,jsxFragmentFactory,jsxImportSource
Controls how JSX constructs are emitted in JavaScript files. This only affects output of JS files that started in .tsx files.
react-jsx: Emit.jsfiles with the JSX changed to_jsxcalls optimized for productionreact-jsxdev: Emit.jsfiles with the JSX changed to_jsxcalls for development onlypreserve: Emit.jsxfiles with the JSX unchangedreact-native: Emit.jsfiles with the JSX unchangedreact: Emit.jsfiles with JSX changed to the equivalentReact.createElementcalls
For example
This sample code:
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 dev transform: "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;
TryPreserve: "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;
TryLegacy React runtime: "react"
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelloWorld = void 0;
const HelloWorld = () => React.createElement("h1", null, "Hello world");
exports.HelloWorld = HelloWorld;
TryThis option can be used on a per-file basis too using an @jsxRuntime comment.
Always use the classic runtime ("react") for this file:
/* @jsxRuntime classic */
export const HelloWorld = () => <h1>Hello world</h1>;Always use the automatic runtime ("react-jsx") for this file:
/* @jsxRuntime automatic */
export const HelloWorld = () => <h1>Hello world</h1>;jsxFactory
Allowed: Any identifier or dotted identifier.
Default:
React.createElementReleased: 2.2
Related: jsx,jsxFragmentFactory,jsxImportSource
Changes the function called in .js files when compiling JSX Elements using the classic JSX runtime. The most common change is to use "h" or "preact.h" instead of the default "React.createElement" if using preact.
For example, this TSX file:
import { h } from "preact";
const HelloWorld = () => <div>Hello</div>;With jsxFactory: "h" looks like:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const preact_1 = require("preact");
const HelloWorld = () => (0, preact_1.h)("div", null, "Hello");
TryThis option can be used on a per-file basis too similar to Babel's /** @jsx h */ directive.
The factory chosen will also affect where the JSX namespace is looked up (for type checking information) before falling back to the global one.
If the factory is defined as React.createElement (the default), the compiler will check for React.JSX before checking for a global JSX. If the factory is defined as h, it will check for h.JSX before a global JSX.
jsxFragmentFactory
Default:
React.FragmentReleased: 4.0
Related: jsx,jsxFactory,jsxImportSource
Specify the JSX fragment factory function to use when targeting react JSX emit with jsxFactory compiler option is specified, e.g. Fragment.
For example with this TSConfig:
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment"
}
}This TSX file:
import { h, Fragment } from "preact";
const HelloWorld = () => (
<>
<div>Hello</div>
</>
);Would look like:
"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")));
TryThis option can be used on a per-file basis too similar to Babel's /* @jsxFrag h */ directive.
For example:
/** @jsx h */
/** @jsxFrag Fragment */
import { h, Fragment } from "preact";
const HelloWorld = () => (
<>
<div>Hello</div>
</>
);TryjsxImportSource
Default:
reactReleased: 4.1
Related: jsx,jsxFactory
Declares the module specifier to be used for importing the jsx and jsxs factory functions when using jsx as "react-jsx" or "react-jsxdev" which were introduced in TypeScript 4.1.
With React 17 the library supports a new form of JSX transformation via a separate import.
For example with this code:
import React from "react";
function App() {
return <h1>Hello World</h1>;
}Using this TSConfig:
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react-jsx"
}
}The emitted JavaScript from TypeScript is:
"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" });
}
TryFor example if you wanted to use "jsxImportSource": "preact", you need a tsconfig like:
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react-jsx",
"jsxImportSource": "preact",
"types": ["preact"]
}
}Which generates code like:
"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" });
}
TryAlternatively, you can use a per-file pragma to set this option, for example:
/** @jsxImportSource preact */
export function App() {
return <h1>Hello World</h1>;
}Would add preact/jsx-runtime as an import for the _jsx factory.
Note: In order for this to work like you would expect, your tsx file must include an export or import so that it is considered a module.
lib
TypeScript includes a default set of type definitions for built-in JS APIs (like Math), as well as type definitions for things found in browser environments (like document). TypeScript also includes APIs for newer JS features matching the target you specify; for example the definition for Map is available if target is ES6 or newer.
You may want to change these for a few reasons:
- Your program doesn't run in a browser, so you don't want the
"dom"type definitions - Your runtime platform provides certain JavaScript API objects (maybe through polyfills), but doesn't yet support the full syntax of a given ECMAScript version
- You have polyfills or native implementations for some, but not all, of a higher level ECMAScript version
In TypeScript 4.5, lib files can be overridden by npm modules, find out more in the blog.
High Level libraries
| Name | Contents |
|---|---|
ES5 | Core definitions for all ES5 functionality |
ES2015 | Additional APIs available in ES2015 (also known as ES6) - array.find, Promise, Proxy, Symbol, Map, Set, Reflect, etc. |
ES6 | Alias for "ES2015" |
ES2016 | Additional APIs available in ES2016 - array.include, etc. |
ES7 | Alias for "ES2016" |
ES2017 | Additional APIs available in ES2017 - Object.entries, Object.values, Atomics, SharedArrayBuffer, date.formatToParts, typed arrays, etc. |
ES2018 | Additional APIs available in ES2018 - async iterables, promise.finally, Intl.PluralRules, regexp.groups, etc. |
ES2019 | Additional APIs available in ES2019 - array.flat, array.flatMap, Object.fromEntries, string.trimStart, string.trimEnd, etc. |
ES2020 | Additional APIs available in ES2020 - string.matchAll, etc. |
ES2021 | Additional APIs available in ES2021 - promise.any, string.replaceAll etc. |
ES2022 | Additional APIs available in ES2022 - array.at, RegExp.hasIndices, etc. |
ES2023 | Additional APIs available in ES2023 - array.with, array.findLast, array.findLastIndex, array.toSorted, array.toReversed, etc. |
ESNext | Additional APIs available in ESNext - This changes as the JavaScript specification evolves |
DOM | DOM definitions - window, document, etc. |
WebWorker | APIs available in WebWorker contexts |
ScriptHost | APIs for the Windows Script Hosting System |
Individual library components
| Name |
|---|
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 |
This list may be out of date, you can see the full list in the TypeScript source code.
libReplacement
TypeScript 4.5 introduced the possibility of substituting the default lib files with custom ones. All built-in library files would first try to be resolved from packages named @typescript/lib-*. For example, you could lock your dom libraries onto a specific version of the @types/web package with the following package.json:
{
"devDependencies": {
"@typescript/lib-dom": "npm:@types/web@0.0.199"
}
}When installed, a package called @typescript/lib-dom should exist, and TypeScript would always look there when searching for lib.dom.d.ts.
The --libReplacement flag allows you to disable this behavior. If you're not using any @typescript/lib-* packages, you can now disable those package lookups with --libReplacement false. In the future, --libReplacement false may become the default, so if you currently rely on the behavior you should consider explicitly enabling it with --libReplacement true.
moduleDetection
Allowed:
legacy,auto,forceDefault: "auto": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.
Released: 4.7
This setting controls how TypeScript determines whether a file is a script or a module.
There are three choices:
"auto"(default) - TypeScript will not only look for import and export statements, but it will also check whether the"type"field in apackage.jsonis set to"module"when running withmodule:nodenextornode16, and check whether the current file is a JSX file when running underjsx:react-jsx."legacy"- The same behavior as 4.6 and prior, usings import and export statements to determine whether a file is a module."force"- Ensures that every non-declaration file is treated as a module.
noLib
Disables the automatic inclusion of any library files. If this option is set, lib is ignored.
TypeScript cannot compile anything without a set of interfaces for key primitives like: Array, Boolean, Function, IArguments, Number, Object, RegExp, and String. It is expected that if you use noLib you will be including your own type definitions for these.
reactNamespace
Default:
ReactReleased: 1.8
Use jsxFactory instead. Specify the object invoked for createElement when targeting react for TSX files.
target
Allowed:
es3,es5,es6/es2015,es2016,es2017,es2018,es2019,es2020,es2021,es2022,es2023,es2024,es2025,esnextDefault:
es2023if module isnode20;esnextif module isnodenext;ES5otherwise.Released: 1.0
Modern browsers support all ES6 features, so ES6 is a good choice. You might choose to set a lower target if your code is deployed to older environments, or a higher target if your code is guaranteed to run in newer environments.
The target setting changes which JS features are downleveled and which are left intact. For example, an arrow function () => this will be turned into an equivalent function expression if target is ES5 or lower.
Changing target also changes the default value of lib. You may "mix and match" target and lib settings as desired, but you could just set target for convenience.
For developer platforms like Node there are baselines for the target, depending on the type of platform and its version. You can find a set of community organized TSConfigs at tsconfig/bases, which has configurations for common platforms and their versions.
The special ESNext value refers to the highest version your version of TypeScript supports. This setting should be used with caution, since it doesn't mean the same thing between different TypeScript versions and can make upgrades less predictable.
useDefineForClassFields
This flag is used as part of migrating to the upcoming standard version of class fields. TypeScript introduced class fields many years before it was ratified in TC39. The latest version of the upcoming specification has a different runtime behavior to TypeScript's implementation but the same syntax.
This flag switches to the upcoming ECMA runtime behavior.
You can read more about the transition in the 3.7 release notes.