diff --git a/runtime/fundamentals/configuration.md b/runtime/fundamentals/configuration.md index f2d1721f3..eb25c1ac5 100644 --- a/runtime/fundamentals/configuration.md +++ b/runtime/fundamentals/configuration.md @@ -345,8 +345,14 @@ sharing code. ::: -See also -[Configuring TypeScript in Deno](/runtime/reference/ts_config_migration/). +If you’re migrating from Node.js, your existing `tsconfig.json` files work +out-of-the-box with Deno. See +[Using tsconfig.json with Deno](/runtime/fundamentals/typescript/#using-tsconfigjson-with-deno) +for details. + +For the full list of supported compiler options, library configuration, and +advanced settings, see +[Configuring TypeScript](/runtime/reference/ts_config_migration/). ## Unstable features diff --git a/runtime/fundamentals/typescript.md b/runtime/fundamentals/typescript.md index fce1bc74e..0d63d28ee 100644 --- a/runtime/fundamentals/typescript.md +++ b/runtime/fundamentals/typescript.md @@ -316,3 +316,67 @@ file, in the `compilerOptions.types` array: ``` This will also augment the global scope with the `polyfilledAPI` function. + +## Configuring TypeScript compiler options + +Deno uses strict and modern TypeScript defaults out of the box, so most projects +don't need any configuration. When you do need to customize compiler behavior, +use the `compilerOptions` field in +[`deno.json`](/runtime/fundamentals/configuration/): + +```json title="deno.json" +{ + "compilerOptions": { + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true + } +} +``` + +See the +[full list of supported compiler options](/runtime/reference/ts_config_migration/#ts-compiler-options). + +## Using `tsconfig.json` with Deno + +If you're migrating a Node.js + TypeScript project, your existing +`tsconfig.json` files will work with Deno's type checker and LSP out of the box. +Deno automatically discovers `tsconfig.json` files in workspace directories that +contain a `deno.json` or `package.json`. + +``` +my-project/ +├── deno.json +├── tsconfig.json # ← discovered automatically +├── src/ +│ └── main.ts +└── packages/ + └── lib/ + ├── package.json + └── tsconfig.json # ← also discovered +``` + +Deno supports the standard `tsconfig.json` fields: `extends`, `files`, +`include`, `exclude`, `references`, and `compilerOptions`. + +:::note + +For Deno-first projects, prefer using `compilerOptions` in `deno.json` instead +of a separate `tsconfig.json`. The `tsconfig.json` compatibility is primarily +for migrating existing Node.js projects. + +::: + +### Precedence rules + +When both `deno.json` and `tsconfig.json` exist: + +1. `compilerOptions` in a parent `deno.json` take precedence over any + `tsconfig.json`. +2. A `tsconfig.json` reference takes precedence over its referrer. +3. For root references, a more deeply nested `tsconfig.json` takes precedence + (e.g. `foo/bar/tsconfig.json` over `foo/tsconfig.json`). + +For the full details on `tsconfig.json` compatibility, compiler options, and +library configuration, see the +[Configuring TypeScript](/runtime/reference/ts_config_migration/) reference. diff --git a/runtime/reference/ts_config_migration.md b/runtime/reference/ts_config_migration.md index bf55e980b..99da8d4cc 100644 --- a/runtime/reference/ts_config_migration.md +++ b/runtime/reference/ts_config_migration.md @@ -13,70 +13,10 @@ oldUrl: - /runtime/fundamentals/types/ --- -Deno’s flexibility shines in its equal treatment of TypeScript and JavaScript. -Whether you’re transitioning from JavaScript to TypeScript or vice versa, Deno -has features to ease the journey. - -## Type Checking JavaScript - -You may wish to make your JavaScript more type-sound without adding type -annotations everywhere. Deno supports using the TypeScript type checker to type -check JavaScript. You can mark individual files by adding the check JavaScript -pragma to the file: - -```js -// @ts-check -``` - -This will cause the type checker to infer type information about the JavaScript -code and raise any issues as diagnostic issues. - -These can be turned on for all JavaScript files in a program by providing a -configuration file with the check JS option set to `true`, as below. Then use -the `--config` option when running on the command line. - -```json -{ - "compilerOptions": { - "checkJs": true - } -} -``` - -## Using JSDoc in JavaScript - -When type-checking JavaScript or importing JavaScript into TypeScript, JSDoc -annotations can provide additional type information beyond what can just be -inferred from the code itself. Deno supports this seamlessly if you annotate -your code inline with the supported -[TypeScript JSDoc](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html). - -For example to set the type of an array use the following JSDoc comment: - -```js -/** @type {string[]} */ -const a = []; -``` - -## Skipping type checking - -You might have TypeScript code that you are experimenting with, where the syntax -is valid but not fully type safe. You can bypass type checking for a whole -program by passing the `--no-check` flag. - -You can also skip whole files being type checked, including JavaScript if you -have check JS enabled, by using the `nocheck` pragma: - -```js -// @ts-nocheck -``` - -## Renaming JS files to TS files - -TypeScript files benefit from the TypeScript compiler being able to do more -thorough safety checks of your code. This is often referred to as _strict mode_. -When you rename a `.js` file to `.ts` you'll might see new type errors that you -TypeScript wasn't able to detect before. +This page covers advanced TypeScript configuration in Deno, including compiler +options, `tsconfig.json` compatibility, and library targeting. For an +introduction to using TypeScript with Deno, see +[TypeScript support](/runtime/fundamentals/typescript/). ## Configuring TypeScript in Deno @@ -273,151 +213,15 @@ code. ## Types and Type Declarations -Deno applies a design principle of _no non-standard module resolution_. When -TypeScript checks a file, it focuses solely on its types. In contrast, the `tsc` -compiler employs intricate logic to resolve those types. By default, `tsc` -expects ambiguous module specifiers with extensions (e.g., `.ts`, `.d.ts` or -`.js`). Deno, however, deals with explicit specifiers. - -Here’s where it gets interesting: Imagine you want to consume a TypeScript file -that’s already transpiled to JavaScript, along with its type definition file -(`mod.js` and `mod.d.ts`). If you import `mod.js` into Deno, it strictly follows -your request and imports the JavaScript file. But here’s the catch: Your code -won’t be as thoroughly type-checked as if TypeScript considered the `mod.d.ts` -file alongside the `mod.js` file. - -To address this, Deno offers two solutions, each catering to specific scenarios: - -**As the Importer:** If you know what types should apply to a JavaScript module, -you can enhance type checking by explicitly specifying the types. - -**As the Supplier:** If you’re the provider or host of the module, everyone -consuming it benefits without worrying about type resolution. - -## Providing types when importing - -If you are consuming a JavaScript module and you have either created types (a -`.d.ts` file) or have otherwise obtained the types you want to use, you can -instruct Deno to use that file when type checking, instead of the JavaScript -file, using the `@ts-types` compiler hint. - -For example if you have a JavaScript module, `coolLib.js`, and a separate -`coolLib.d.ts` file, you would import it like this: - -```ts -// @ts-types="./coolLib.d.ts" -import * as coolLib from "./coolLib.js"; -``` - -When you’re performing type checking on `coolLib` and using it in your file, the -TypeScript type definitions from `coolLib.d.ts` will take precedence over -examining the JavaScript file. - -:::note - -In the past the `@ts-types` directive was called `@deno-types`. This alias still -works, but is not recommended anymore. Use `@ts-types`. - -::: - -## Providing types when hosting +For information on providing type declarations for JavaScript modules (using +`@ts-types`, `@ts-self-types`, `X-TypeScript-Types` headers, and `.d.ts` files), +see +[Providing declaration files](/runtime/fundamentals/typescript/#providing-declaration-files) +in the TypeScript fundamentals guide. -If you have control over the module’s source code or how the file is hosted on a -web server, there are two ways to let Deno know about the types for a specific -module (which won’t require any special action from the importer). - -### @ts-self-types - -If you are providing a JavaScript file, and want to provide a declaration file -that contains the types for this file, you can specify a `@ts-self-types` -directive in the JS file, pointing to the declaration file. - -For example, if you make a `coolLib.js` library, and write its type definitions -in `coolLib.d.ts` the `ts-self-types` directive would look like this: - -```js title="coolLib.js" -// @ts-self-types="./coolLib.d.ts" - -// ... the rest of the JavaScript ... -``` - -### X-TypeScript-Types - -Deno supports a header for remote modules that instructs Deno where to locate -the types for a given module. For example, a response for -`https://example.com/coolLib.js` might look something like this: - -```console -HTTP/1.1 200 OK -Content-Type: application/javascript; charset=UTF-8 -Content-Length: 648 -X-TypeScript-Types: ./coolLib.d.ts -``` - -When seeing this header, Deno would attempt to retrieve -`https://example.com/coolLib.d.ts` and use that when type checking the original -module. - -## Using ambient or global types - -Overall it is better to use module/UMD type definitions with Deno, where a -module expressly imports the types it depends upon. Modular type definitions can -express -[augmentation of the global scope](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html) -via the `declare global` in the type definition. For example: - -```ts -declare global { - var AGlobalString: string; -} -``` - -This would make `AGlobalString` available in the global namespace when importing -the type definition. - -In some cases though, when leveraging other existing type libraries, it may not -be possible to leverage modular type definitions. Therefore there are ways to -include arbitrary type definitions when type checking programmes. - -### Triple-slash directive - -This option couples the type definitions to the code itself. By adding a -triple-slash `types` directive in a TS file (not a JS file!), near the type of a -module, type checking the file will include the type definition. For example: - -```ts -/// -``` - -The specifier provided is resolved just like any other specifier in Deno, which -means it requires an extension, and is relative to the module referencing it. It -can be a fully qualified URL as well: - -```ts -/// -``` - -### Supplying "types" in deno.json - -Another option is to provide a `"types"` value to the `"compilerOptions"` in -your `deno.json`. For example: - -```json title="deno.json" -{ - "compilerOptions": { - "types": [ - "./types.d.ts", - "https://deno.land/x/pkg@1.0.0/types.d.ts", - "/Users/me/pkg/types.d.ts" - ] - } -} -``` - -Like the triple-slash reference above, the specifier supplied in the `"types"` -array will be resolved like other specifiers in Deno. In the case of relative -specifiers, it will be resolved relative to the path to the config file. Make -sure to tell Deno to use this file by specifying `--config=path/to/file` flag. +For information on augmenting global types using `declare global` or `.d.ts` +files, see +[Augmenting global types](/runtime/fundamentals/typescript/#augmenting-global-types). ## Type Checking Web Workers @@ -463,13 +267,9 @@ library files. For example: } ``` -Then when running deno subcommand, you would need to pass the -`--config path/to/file` argument, or if you are using an IDE which leverages the -Deno language server, set the `deno.config` setting. - -If you also have non-worker scripts, you will either need to omit the `--config` -argument, or have one that is configured to meet the needs of your non-worker -scripts. +If you also have non-worker scripts, consider using +[workspaces](/runtime/fundamentals/workspaces/) so each workspace member can +have its own `compilerOptions`. ## Important points