Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions packages/documentation/copy/en/handbook-v2/Basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,11 @@ to
Why did this happen?

Template strings are a feature from a version of ECMAScript called ECMAScript 2015 (a.k.a. ECMAScript 6, ES2015, ES6, etc. - _don't ask_).
TypeScript has the ability to rewrite code from newer versions of ECMAScript to older ones such as ECMAScript 3 or ECMAScript 5 (a.k.a. ES5).
TypeScript has the ability to rewrite code from newer versions of ECMAScript to older supported versions such as ECMAScript 2015.
This process of moving from a newer or "higher" version of ECMAScript down to an older or "lower" one is sometimes called _downleveling_.

By default TypeScript targets ES5, an extremely old version of ECMAScript.
We could have chosen something a little bit more recent by using the [`target`](/tsconfig#target) option.
By default TypeScript targets the most recent supported ECMAScript version.
We could have chosen something older by using the [`target`](/tsconfig#target) option.
Running with `--target es2015` changes TypeScript to target ECMAScript 2015, meaning code should be able to run wherever ECMAScript 2015 is supported.
So running `tsc --target es2015 hello.ts` gives us the following output:

Expand All @@ -403,15 +403,14 @@ function greet(person, date) {
greet("Maddison", new Date());
```

> While the default target is ES5, the great majority of current browsers support ES2015.
> Most developers can therefore safely specify ES2015 or above as a target, unless compatibility with certain ancient browsers is important.
> Modern runtimes support ES2015 and newer.
> Most developers can therefore safely use a recent target unless compatibility with older browsers is important.

## Strictness

Different users come to TypeScript looking for different things in a type-checker.
Some people are looking for a more loose opt-in experience which can help validate only some parts of their program, and still have decent tooling.
This is the default experience with TypeScript, where types are optional, inference takes the most lenient types, and there's no checking for potentially `null`/`undefined` values.
Much like how `tsc` emits in the face of errors, these defaults are put in place to stay out of your way.
You can configure TypeScript for a looser opt-in experience where types are optional, inference takes more lenient types, and there's less checking for potentially `null`/`undefined` values.
If you're migrating existing JavaScript, that might be a desirable first step.

In contrast, a lot of users prefer to have TypeScript validate as much as it can straight away, and that's why the language provides strictness settings as well.
Expand Down
4 changes: 2 additions & 2 deletions packages/documentation/copy/en/handbook-v2/Modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Before we start, it's important to understand what TypeScript considers a module
The JavaScript specification declares that any JavaScript files without an `import` declaration, `export`, or top-level `await` should be considered a script and not a module.


Inside a script file variables and types are declared to be in the shared global scope, and it's assumed that you'll either use the [`outFile`](/tsconfig#outFile) compiler option to join multiple input files into one output file, or use multiple `<script>` tags in your HTML to load these files (in the correct order!).
Inside a script file variables and types are declared to be in the shared global scope, and it's assumed that you'll use multiple `<script>` tags in your HTML to load these files in the correct order.

If you have a file that doesn't currently have any `import`s or `export`s, but you want to be treated as a module, add the line:

Expand Down Expand Up @@ -404,4 +404,4 @@ You can see all of the available options and what their emitted JavaScript code

## TypeScript namespaces

TypeScript has its own module format called `namespaces` which pre-dates the ES Modules standard. This syntax has a lot of useful features for creating complex definition files, and still sees active use [in DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped). While not deprecated, the majority of the features in namespaces exist in ES Modules and we recommend you use that to align with JavaScript's direction. You can learn more about namespaces in [the namespaces reference page](/docs/handbook/namespaces.html).
TypeScript has its own module format called `namespaces` which pre-dates the ES Modules standard. This syntax has a lot of useful features for creating complex definition files, and still sees active use [in DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped). While the `namespace` keyword is not deprecated, the legacy `module` keyword for namespaces is deprecated in TypeScript 6.0. The majority of the features in namespaces exist in ES Modules and we recommend you use that to align with JavaScript's direction. You can learn more about namespaces in [the namespaces reference page](/docs/handbook/namespaces.html).
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ const args = [8, 5] as const;
const angle = Math.atan2(...args);
```

Using rest arguments may require turning on [`downlevelIteration`](/tsconfig#downlevelIteration) when targeting older runtimes.
Using rest arguments may require a recent [`target`](/tsconfig#target) when targeting older runtimes.

<!-- TODO link to downlevel iteration -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ For example, the `startsWith` method of strings is available only starting with
Being aware of what version of JavaScript your code ultimately runs on is important because you don't want to use APIs that are from a newer version than the platform you deploy to.
This is one function of the [`target`](/tsconfig#target) compiler setting.

TypeScript helps with this problem by varying which `lib` files are included by default based on your [`target`](/tsconfig#target) setting.
For example, if [`target`](/tsconfig#target) is `ES5`, you will see an error if trying to use the `startsWith` method, because that method is only available in `ES6` or later.
TypeScript helps with this problem by varying which `lib` files are included by default based on your [`target`](/tsconfig#target) setting.
For example, if [`target`](/tsconfig#target) is `ES2015`, you will see an error if trying to use the `replaceAll` method, because that method is only available in `ES2021` or later.

### `lib` setting

Expand Down Expand Up @@ -85,7 +85,8 @@ For example, if you installed the `react` npm package, you can install its corre
npm install --save-dev @types/react
```

TypeScript automatically finds type definitions under `node_modules/@types`, so there's no other step needed to get these types available in your program.
When you import a package in your source code, TypeScript will automatically look for its type definitions, including definitions under `node_modules/@types`.
If an `@types` package provides globals that you use without importing, such as `process` from `@types/node` or `describe` from `@types/jest`, add the package name to the [`types`](/tsconfig#types) field of your `tsconfig.json`.

### Your Own Definitions

Expand Down
18 changes: 8 additions & 10 deletions packages/documentation/copy/en/modules-reference/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ export default "default export";

#### Examples

> Output is shown with `esModuleInterop: false`.
> Output is shown with `esModuleInterop` enabled.

```ts
// @Filename: main.ts
Expand Down Expand Up @@ -467,7 +467,6 @@ System.register(["mod"], function (exports_1, context_1) {
- Designed for AMD loaders like RequireJS.
- You probably shouldn’t use this. Use a bundler instead.
- Emitted files are AMD modules, but dependencies may be any format.
- Supports `outFile`.

#### Examples

Expand Down Expand Up @@ -747,17 +746,16 @@ Multiple file paths can be provided for a path mapping. If resolution fails for

#### `baseUrl`

> `baseUrl` was designed for use with AMD module loaders. If you aren’t using an AMD module loader, you probably shouldn’t use `baseUrl`. Since TypeScript 4.1, `baseUrl` is no longer required to use [`paths`](#paths) and should not be used just to set the directory `paths` values are resolved from.
> `baseUrl` was designed for use with AMD module loaders. If you aren’t using an AMD module loader, you probably shouldn’t use `baseUrl`. Since TypeScript 4.1, `baseUrl` is no longer required to use [`paths`](#paths), and in TypeScript 6.0 it is deprecated.

The `baseUrl` compiler option can be combined with any `moduleResolution` mode and specifies a directory that bare specifiers (module specifiers that don’t begin with `./`, `../`, or `/`) are resolved from. `baseUrl` has a higher precedence than [`node_modules` package lookups](#node_modules-package-lookups) in `moduleResolution` modes that support them.

When performing a `baseUrl` lookup, resolution proceeds with the same rules as other relative path resolutions. For example, in a `moduleResolution` mode that supports [extensionless relative paths](#extensionless-relative-paths) a module specifier `"some-file"` may resolve to `/src/some-file.ts` if `baseUrl` is set to `/src`.
For code that used `baseUrl` as a common prefix for [`paths`](#paths), remove `baseUrl` and add that prefix to each `paths` entry.
For code that used `baseUrl` as a lookup root for arbitrary bare specifiers, use an explicit catch-all `paths` entry instead.

Resolution of relative module specifiers are never affected by the `baseUrl` option.

#### `node_modules` package lookups

Node.js treats module specifiers that aren’t relative paths, absolute paths, or URLs as references to packages that it looks up in `node_modules` subdirectories. Bundlers conveniently adopted this behavior to allow their users to use the same dependency management system, and often even the same dependencies, as they would in Node.js. All of TypeScript’s `moduleResolution` options except `classic` support `node_modules` lookups. (`classic` supports lookups in `node_modules/@types` when other means of resolution fail, but never looks for packages in `node_modules` directly.) Every `node_modules` package lookup has the following structure (beginning after higher precedence bare specifier rules, like `paths`, `baseUrl`, self-name imports, and package.json `"imports"` lookups have been exhausted):
Node.js treats module specifiers that aren’t relative paths, absolute paths, or URLs as references to packages that it looks up in `node_modules` subdirectories. Bundlers conveniently adopted this behavior to allow their users to use the same dependency management system, and often even the same dependencies, as they would in Node.js. All of TypeScript’s module resolution modes for modern code support `node_modules` lookups. Every `node_modules` package lookup has the following structure (beginning after higher precedence bare specifier rules, like `paths`, self-name imports, and package.json `"imports"` lookups have been exhausted):

1. For each ancestor directory of the importing file, if a `node_modules` directory exists within it:
1. If a directory with the same name as the package exists within `node_modules`:
Expand Down Expand Up @@ -1153,7 +1151,7 @@ import { foo } from "pkg";

Recall that in `--module nodenext --moduleResolution nodenext`, the `--module` setting first [determines](#module-format-detection) whether the import will be emitted to the `.js` file as an `import` or `require` call, then passes that information to TypeScript’s module resolver, which decides whether to match `"import"` or `"require"` conditions in `"pkg"`’s package.json `"exports"` accordingly. Let’s assume that there’s no package.json in scope of this file. The file extension is `.ts`, so the output file extension will be `.js`, which Node.js will interpret as CommonJS, so TypeScript will emit this `import` as a `require` call. So, the module resolver will use the `require` condition as it resolves `"exports"` from `"pkg"`.

The same process happens in `--moduleResolution bundler`, but the rules for deciding whether to emit an `import` or `require` call for this import statement will be different, since `--moduleResolution bundler` necessitates using [`--module esnext`](#es2015-es2020-es2022-esnext) or [`--module preserve`](#preserve). In both of those modes, ESM `import` declarations always emit as ESM `import` declarations, so TypeScript’s module resolver will receive that information and use the `"import"` condition as it resolves `"exports"` from `"pkg"`.
The same process happens in `--moduleResolution bundler`, but the rules for deciding whether to emit an `import` or `require` call for this import statement will be different. If `--moduleResolution bundler` is paired with [`--module esnext`](#es2015-es2020-es2022-esnext) or [`--module preserve`](#preserve), ESM `import` declarations emit as ESM `import` declarations, so TypeScript’s module resolver will receive that information and use the `"import"` condition as it resolves `"exports"` from `"pkg"`.

This explanation may be somewhat unintuitive, since `--moduleResolution bundler` is usually used in combination with `--noEmit`—bundlers typically process raw `.ts` files and perform module resolution on untransformed `import`s or `require`s. However, for consistency, TypeScript still uses the hypothetical emit decided by `module` to inform module resolution and type checking. This makes [`--module preserve`](#preserve) the best choice whenever a runtime or bundler is operating on raw `.ts` files, since it implies no transformation. Under `--module preserve --moduleResolution bundler`, you can write imports and requires in the same file that will resolve with the `import` and `require` conditions, respectively:

Expand All @@ -1166,7 +1164,7 @@ import pkg2 = require("pkg"); // Resolved with "require" condition

#### Implied and enforced options

- `--moduleResolution bundler` must be paired with `--module esnext` or `--module preserve`.
- `--moduleResolution bundler` can be paired with `--module esnext`, `--module preserve`, or `--module commonjs`.
- `--moduleResolution bundler` implies `--allowSyntheticDefaultImports`.

#### Supported features
Expand All @@ -1184,7 +1182,7 @@ import pkg2 = require("pkg"); // Resolved with "require" condition

### `node10` (formerly known as `node`)

`--moduleResolution node` was renamed to `node10` (keeping `node` as an alias for backward compatibility) in TypeScript 5.0. It reflects the CommonJS module resolution algorithm as it existed in Node.js versions earlier than v12. It should no longer be used.
`--moduleResolution node` was renamed to `node10` (keeping `node` as an alias for backward compatibility) in TypeScript 5.0. It reflects the CommonJS module resolution algorithm as it existed in Node.js versions earlier than v12. It is deprecated in TypeScript 6.0 and should no longer be used.

#### Supported features

Expand Down
6 changes: 3 additions & 3 deletions packages/documentation/copy/en/modules-reference/Theory.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ and still claim to implement “standards-compliant ESM.” Needless to say, Typ

The available `moduleResolution` options are:

- [**`classic`**](/docs/handbook/modules/reference.html#classic): TypeScript’s oldest module resolution mode, this is unfortunately the default when `module` is set to anything other than `commonjs`, `node16`, or `nodenext`. It was probably made to provide best-effort resolution for a wide range of [RequireJS](https://requirejs.org/docs/api.html#packages) configurations. It should not be used for new projects (or even old projects that don’t use RequireJS or another AMD module loader), and is scheduled for deprecation in TypeScript 6.0.
- [**`node10`**](/docs/handbook/modules/reference.html#node10-formerly-known-as-node): Formerly known as `node`, this is the unfortunate default when `module` is set to `commonjs`. It’s a pretty good model of Node.js versions older than v12, and sometimes it’s a passable approximation of how most bundlers do module resolution. It supports looking up packages from `node_modules`, loading directory `index.js` files, and omitting `.js` extensions in relative module specifiers. Because Node.js v12 introduced different module resolution rules for ES modules, though, it’s a very bad model of modern versions of Node.js. It should not be used for new projects.
- [**`classic`**](/docs/handbook/modules/reference.html#classic): TypeScript’s oldest module resolution mode. It was probably made to provide best-effort resolution for a wide range of [RequireJS](https://requirejs.org/docs/api.html#packages) configurations. It is deprecated in TypeScript 6.0 and should not be used.
- [**`node10`**](/docs/handbook/modules/reference.html#node10-formerly-known-as-node): Formerly known as `node`, this reflects Node.js versions older than v12. It supports looking up packages from `node_modules`, loading directory `index.js` files, and omitting `.js` extensions in relative module specifiers. Because Node.js v12 introduced different module resolution rules for ES modules, though, it’s a very bad model of modern versions of Node.js. It is deprecated in TypeScript 6.0 and should not be used for new projects.
- [**`node16`**](/docs/handbook/modules/reference.html#node16-nodenext-1): This is the counterpart of `--module node16` and `--module node18` and is set by default with that `module` setting. Node.js v12 and later support both ESM and CJS, each of which uses its own module resolution algorithm. In Node.js, module specifiers in import statements and dynamic `import()` calls are not allowed to omit file extensions or `/index.js` suffixes, while module specifiers in `require` calls are. This module resolution mode understands and enforces this restriction where necessary, as determined by the [module format detection rules](#module-format-detection) instated by `--module node16`/`node18`. (For `node16` and `nodenext`, `module` and `moduleResolution` go hand-in-hand: setting one to `node16` or `nodenext` while setting the other to something else is an error.)
- [**`nodenext`**](/docs/handbook/modules/reference.html#node16-nodenext-1): Currently identical to `node16`, this is the counterpart of `--module nodenext` and is set by default with that `module` setting. It’s intended to be a forward-looking mode that will support new Node.js module resolution features as they’re added.
- [**`bundler`**](/docs/handbook/modules/reference.html#bundler): Node.js v12 introduced some new module resolution features for importing npm packages—the `"exports"` and `"imports"` fields of `package.json`—and many bundlers adopted those features without also adopting the stricter rules for ESM imports. This module resolution mode provides a base algorithm for code targeting a bundler. It supports `package.json` `"exports"` and `"imports"` by default, but can be configured to ignore them. It requires setting `module` to `esnext`.
- [**`bundler`**](/docs/handbook/modules/reference.html#bundler): Node.js v12 introduced some new module resolution features for importing npm packages—the `"exports"` and `"imports"` fields of `package.json`—and many bundlers adopted those features without also adopting the stricter rules for ESM imports. This module resolution mode provides a base algorithm for code targeting a bundler. It supports `package.json` `"exports"` and `"imports"` by default, but can be configured to ignore them.

### TypeScript imitates the host’s module resolution, but with types

Expand Down
Loading