From f34b2a8c5c36bf1cb6d53ae98521baf2daca0b13 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Wed, 5 Nov 2025 18:23:29 +0100 Subject: [PATCH] module: mark type stripping as stable --- doc/api/cli.md | 42 ++++++++++--------- doc/api/process.md | 6 ++- doc/api/test.md | 4 +- doc/api/typescript.md | 13 ++++-- .../advocacy-ambassador-program.md | 6 +-- doc/node-config-schema.json | 6 +-- doc/node.1 | 4 +- lib/internal/bootstrap/node.js | 2 +- lib/internal/main/eval_stdin.js | 2 +- lib/internal/main/eval_string.js | 2 +- lib/internal/main/worker_thread.js | 2 +- lib/internal/modules/cjs/loader.js | 2 +- lib/internal/modules/esm/formats.js | 2 +- lib/internal/modules/esm/get_format.js | 4 +- lib/internal/modules/run_main.js | 2 +- lib/internal/process/execution.js | 2 +- lib/internal/test_runner/utils.js | 2 +- src/node_options.cc | 9 ++-- src/node_options.h | 2 +- 19 files changed, 64 insertions(+), 50 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 8f425b0c8343b0..b83e98694011f9 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -977,7 +977,7 @@ only recognizes double `"` for quoting. In Powershell or Git bash, both `'` and `"` are usable. It is possible to run code containing inline types unless the -[`--no-experimental-strip-types`][] flag is provided. +[`--no-strip-types`][] flag is provided. ### `--experimental-addon-modules` @@ -1586,7 +1586,7 @@ changes: This configures Node.js to interpret `--eval` or `STDIN` input as CommonJS or as an ES module. Valid values are `"commonjs"`, `"module"`, `"module-typescript"` and `"commonjs-typescript"`. -The `"-typescript"` values are not available with the flag `--no-experimental-strip-types`. +The `"-typescript"` values are not available with the flag `--no-strip-types`. The default is no value, or `"commonjs"` if `--no-experimental-detect-module` is passed. If `--input-type` is not provided, @@ -1902,23 +1902,6 @@ changes: Disable the experimental [`node:sqlite`][] module. -### `--no-experimental-strip-types` - - - -> Stability: 1.2 - Release candidate - -Disable experimental type-stripping for TypeScript files. -For more information, see the [TypeScript type-stripping][] documentation. - ### `--no-experimental-websocket` + +Disable type-stripping for TypeScript files. +For more information, see the [TypeScript type-stripping][] documentation. + ### `--no-warnings` > Stability: 1.2 - Release candidate @@ -2009,7 +2013,7 @@ added: A value that is `"strip"` by default, `"transform"` if Node.js is run with `--experimental-transform-types`, and `false` if -Node.js is run with `--no-experimental-strip-types`. +Node.js is run with `--no-strip-types`. ## `process.features.uv` diff --git a/doc/api/test.md b/doc/api/test.md index d566c1ddd7cd82..21349b46b702e8 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -514,7 +514,7 @@ By default, Node.js will run all files matching these patterns: * `**/test.{cjs,mjs,js}` * `**/test/**/*.{cjs,mjs,js}` -Unless [`--no-experimental-strip-types`][] is supplied, the following +Unless [`--no-strip-types`][] is supplied, the following additional patterns are also matched: * `**/*.test.{cts,mts,ts}` @@ -3996,7 +3996,7 @@ Can be used to abort test subtasks when the test has been aborted. [`--experimental-test-coverage`]: cli.md#--experimental-test-coverage [`--experimental-test-module-mocks`]: cli.md#--experimental-test-module-mocks [`--import`]: cli.md#--importmodule -[`--no-experimental-strip-types`]: cli.md#--no-experimental-strip-types +[`--no-strip-types`]: cli.md#--no-strip-types [`--test-concurrency`]: cli.md#--test-concurrency [`--test-coverage-exclude`]: cli.md#--test-coverage-exclude [`--test-coverage-include`]: cli.md#--test-coverage-include diff --git a/doc/api/typescript.md b/doc/api/typescript.md index b5b7017d5e6317..74593ea807c372 100644 --- a/doc/api/typescript.md +++ b/doc/api/typescript.md @@ -2,6 +2,9 @@ -> Stability: 1.2 - Release candidate +> Stability: 2 - Stable ## Enabling @@ -60,6 +63,10 @@ To use TypeScript with full support for all TypeScript features, including By default Node.js will execute TypeScript files that contains only @@ -68,7 +75,7 @@ Node.js will replace TypeScript syntax with whitespace, and no type checking is performed. To enable the transformation of non erasable TypeScript syntax, which requires JavaScript code generation, such as `enum` declarations, parameter properties use the flag [`--experimental-transform-types`][]. -To disable this feature, use the flag [`--no-experimental-strip-types`][]. +To disable this feature, use the flag [`--no-strip-types`][]. Node.js ignores `tsconfig.json` files and therefore features that depend on settings within `tsconfig.json`, @@ -219,7 +226,7 @@ with `#`. [ES Modules]: esm.md [Full TypeScript support]: #full-typescript-support [`--experimental-transform-types`]: cli.md#--experimental-transform-types -[`--no-experimental-strip-types`]: cli.md#--no-experimental-strip-types +[`--no-strip-types`]: cli.md#--no-strip-types [`ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX`]: errors.md#err_unsupported_typescript_syntax [`tsconfig` "paths"]: https://www.typescriptlang.org/tsconfig/#paths [`tsx`]: https://tsx.is/ diff --git a/doc/contributing/advocacy-ambassador-program.md b/doc/contributing/advocacy-ambassador-program.md index f58e77fc4c426d..6275003c82512d 100644 --- a/doc/contributing/advocacy-ambassador-program.md +++ b/doc/contributing/advocacy-ambassador-program.md @@ -226,7 +226,7 @@ You can find their contact email in the [`README.md`](../../README.md#tsc-techni ##### Goal -The goal is to raise awareness of the Node.js TypeScript Type Stripping in the JavaScript ecosystem. +The goal is to raise awareness of the Node.js TypeScript Type stripping in the JavaScript ecosystem. Some of the things to highlight include: * The benefits and limitations of the current implementation. @@ -271,7 +271,7 @@ with projects learning from one another and their users. | [reading environment](https://nodejs.org/api/cli.html#--env-filefile) | [20.6.0](https://nodejs.org/en/blog/release/v20.6.0) | Active Development | | [styling output](https://nodejs.org/docs/latest-v22.x/api/util.html#utilstyletextformat-text-options) | [20.12.0](https://nodejs.org/en/blog/release/v20.12.0) | Stable, as of [22.13.0](https://github.com/nodejs/node/pull/56329) | | [run scripts](https://nodejs.org/docs/latest/api/cli.html#--run) | [22.0.0](https://nodejs.org/en/blog/release/v22.0.0) | Stable, as of 22.0.0 | -| [run TypeScript](https://nodejs.org/api/cli.html#--experimental-strip-types) | [22.6.0](https://nodejs.org/en/blog/release/v22.6.0) | Active Development | +| [run TypeScript](https://nodejs.org/api/cli.html#--strip-types) | [22.6.0](https://nodejs.org/en/blog/release/v22.6.0) | Stable, as of REPLACEME | ##### Related Links @@ -284,7 +284,7 @@ with projects learning from one another and their users. * * * -* +* diff --git a/doc/node-config-schema.json b/doc/node-config-schema.json index 3f7d6a93de270d..893f55d9251ca4 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -177,9 +177,6 @@ "experimental-sqlite": { "type": "boolean" }, - "experimental-strip-types": { - "type": "boolean" - }, "experimental-transform-types": { "type": "boolean" }, @@ -361,6 +358,9 @@ "stack-trace-limit": { "type": "number" }, + "strip-types": { + "type": "boolean" + }, "test-coverage-branches": { "type": "number" }, diff --git a/doc/node.1 b/doc/node.1 index ba9af3ac6a2f31..72800cd364222b 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -216,8 +216,8 @@ Disable top-level await keyword support in REPL. .It Fl -no-experimental-sqlite Disable the experimental node:sqlite module. . -.It Fl -no-experimental-strip-types -Disable experimental type-stripping for TypeScript files. +.It Fl -no-strip-types +Disable type-stripping for TypeScript files. . .It Fl -experimental-vm-modules Enable experimental ES module support in VM module. diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index 09ec85a25c1e73..1a93a560b8790d 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -334,7 +334,7 @@ ObjectDefineProperty(process.features, 'typescript', { if (kTypeStrippingMode === null) { if (getOptionValue('--experimental-transform-types')) { kTypeStrippingMode = 'transform'; - } else if (getOptionValue('--experimental-strip-types')) { + } else if (getOptionValue('--strip-types')) { kTypeStrippingMode = 'strip'; } else { kTypeStrippingMode = false; diff --git a/lib/internal/main/eval_stdin.js b/lib/internal/main/eval_stdin.js index b06bfa8c2a7640..7a972aeb9b4d00 100644 --- a/lib/internal/main/eval_stdin.js +++ b/lib/internal/main/eval_stdin.js @@ -29,7 +29,7 @@ readStdin((code) => { const print = getOptionValue('--print'); const shouldLoadESM = getOptionValue('--import').length > 0; const inputType = getOptionValue('--input-type'); - const tsEnabled = getOptionValue('--experimental-strip-types'); + const tsEnabled = getOptionValue('--strip-types'); if (inputType === 'module') { evalModuleEntryPoint(code, print); } else if (inputType === 'module-typescript' && tsEnabled) { diff --git a/lib/internal/main/eval_string.js b/lib/internal/main/eval_string.js index ee402f50fbdd2b..998c3fb4ada52d 100644 --- a/lib/internal/main/eval_string.js +++ b/lib/internal/main/eval_string.js @@ -32,7 +32,7 @@ const code = getOptionValue('--eval'); const print = getOptionValue('--print'); const shouldLoadESM = getOptionValue('--import').length > 0 || getOptionValue('--experimental-loader').length > 0; const inputType = getOptionValue('--input-type'); -const tsEnabled = getOptionValue('--experimental-strip-types'); +const tsEnabled = getOptionValue('--strip-types'); if (inputType === 'module') { evalModuleEntryPoint(code, print); } else if (inputType === 'module-typescript' && tsEnabled) { diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js index ec13dfa2a25a2e..8a58dc0cba0f49 100644 --- a/lib/internal/main/worker_thread.js +++ b/lib/internal/main/worker_thread.js @@ -166,7 +166,7 @@ port.on('message', (message) => { value: filename, }); ArrayPrototypeSplice(process.argv, 1, 0, name); - const tsEnabled = getOptionValue('--experimental-strip-types'); + const tsEnabled = getOptionValue('--strip-types'); const inputType = getOptionValue('--input-type'); if (inputType === 'module-typescript' && tsEnabled) { diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 8bd89305e2b20a..b8aac380da7974 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1856,7 +1856,7 @@ function getRequireESMError(mod, pkg, content, filename) { */ Module._extensions['.js'] = function(module, filename) { let format, pkg; - const tsEnabled = getOptionValue('--experimental-strip-types'); + const tsEnabled = getOptionValue('--strip-types'); if (StringPrototypeEndsWith(filename, '.cjs')) { format = 'commonjs'; } else if (StringPrototypeEndsWith(filename, '.mjs')) { diff --git a/lib/internal/modules/esm/formats.js b/lib/internal/modules/esm/formats.js index 8d4af32b612d84..6a18bd992fa1d9 100644 --- a/lib/internal/modules/esm/formats.js +++ b/lib/internal/modules/esm/formats.js @@ -24,7 +24,7 @@ if (experimentalAddonModules) { extensionFormatMap['.node'] = 'addon'; } -if (getOptionValue('--experimental-strip-types')) { +if (getOptionValue('--strip-types')) { extensionFormatMap['.ts'] = 'module-typescript'; extensionFormatMap['.mts'] = 'module-typescript'; extensionFormatMap['.cts'] = 'commonjs-typescript'; diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js index 01584983c16a2a..48ccb97a6244ea 100644 --- a/lib/internal/modules/esm/get_format.js +++ b/lib/internal/modules/esm/get_format.js @@ -132,7 +132,7 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE } return format; } - if (ext === '.ts' && getOptionValue('--experimental-strip-types')) { + if (ext === '.ts' && getOptionValue('--strip-types')) { const { type: packageType, pjsonPath, exists: foundPackageJson } = getPackageScopeConfig(url); if (packageType !== 'none') { return `${packageType}-typescript`; @@ -140,7 +140,7 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE // The controlling `package.json` file has no `type` field. // `source` is undefined when this is called from `defaultResolve`; // but this gets called again from `defaultLoad`/`defaultLoadSync`. - // Since experimental-strip-types depends on detect-module, we always return null if source is undefined. + // Since strip-types depends on detect-module, we always return null if source is undefined. if (!source) { return null; } const { stringify } = require('internal/modules/helpers'); const { stripTypeScriptModuleTypes } = require('internal/modules/typescript'); diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js index d337eeca801b9c..2974459755ec25 100644 --- a/lib/internal/modules/run_main.js +++ b/lib/internal/modules/run_main.js @@ -67,7 +67,7 @@ function shouldUseESMLoader(mainPath) { if (mainPath && StringPrototypeEndsWith(mainPath, '.wasm')) { return true; } if (!mainPath || StringPrototypeEndsWith(mainPath, '.cjs')) { return false; } - if (getOptionValue('--experimental-strip-types')) { + if (getOptionValue('--strip-types')) { if (!mainPath || StringPrototypeEndsWith(mainPath, '.cts')) { return false; } // This will likely change in the future to start with commonjs loader by default if (mainPath && StringPrototypeEndsWith(mainPath, '.mts')) { return true; } diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index fc5f7d09ac33a1..f2407949c2a1b6 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -84,7 +84,7 @@ function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) { const baseUrl = pathToFileURL(module.filename).href; if (shouldUseModuleEntryPoint(name, body)) { - return getOptionValue('--experimental-strip-types') ? + return getOptionValue('--strip-types') ? evalTypeScriptModuleEntryPoint(body, print) : evalModuleEntryPoint(body, print); } diff --git a/lib/internal/test_runner/utils.js b/lib/internal/test_runner/utils.js index dabfccf6c4f4a4..937c52b08493ea 100644 --- a/lib/internal/test_runner/utils.js +++ b/lib/internal/test_runner/utils.js @@ -61,7 +61,7 @@ const kRegExpPattern = /^\/(.*)\/([a-z]*)$/; const kPatterns = ['test', 'test/**/*', 'test-*', '*[._-]test']; const kFileExtensions = ['js', 'mjs', 'cjs']; -if (getOptionValue('--experimental-strip-types')) { +if (getOptionValue('--strip-types')) { ArrayPrototypePush(kFileExtensions, 'ts', 'mts', 'cts'); } const kDefaultPattern = `**/{${ArrayPrototypeJoin(kPatterns, ',')}}.{${ArrayPrototypeJoin(kFileExtensions, ',')}}`; diff --git a/src/node_options.cc b/src/node_options.cc index 687cbd5398535f..6f5475c3d9bd14 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -1071,17 +1071,18 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { "ES module to preload (option can be repeated)", &EnvironmentOptions::preload_esm_modules, kAllowedInEnvvar); - AddOption("--experimental-strip-types", - "Experimental type-stripping for TypeScript files.", - &EnvironmentOptions::experimental_strip_types, + AddOption("--strip-types", + "Type-stripping for TypeScript files.", + &EnvironmentOptions::strip_types, kAllowedInEnvvar, true); + AddAlias("--experimental-strip-types", "--strip-types"); AddOption("--experimental-transform-types", "enable transformation of TypeScript-only" "syntax into JavaScript code", &EnvironmentOptions::experimental_transform_types, kAllowedInEnvvar); - Implies("--experimental-transform-types", "--experimental-strip-types"); + Implies("--experimental-transform-types", "--strip-types"); Implies("--experimental-transform-types", "--enable-source-maps"); AddOption("--interactive", "always enter the REPL even if stdin does not appear " diff --git a/src/node_options.h b/src/node_options.h index 79b90d59014cb9..b08800a5fa1ed1 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -259,7 +259,7 @@ class EnvironmentOptions : public Options { std::vector preload_esm_modules; - bool experimental_strip_types = true; + bool strip_types = true; bool experimental_transform_types = false; std::vector user_argv;