Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module: add --experimental-strip-input-types #56273

Closed
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: 13 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,18 @@ added:

Use this flag to enable [ShadowRealm][] support.

### `--experimental-strip-input-types`

<!-- YAML
added: REPLACEME
-->

> Stability: 1.1 - Active development

Enable experimental type-stripping for `--eval`.
Implies [`--experimental-strip-types`][].
For more information, see the [TypeScript type-stripping][] documentation.
Comment on lines +998 to +1008
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this could just be a new value for --input-type, so like --input-type=strip-types; could that work? And I guess it would rely on syntax detection to determine format, or it would just always assume ESM since TypeScript syntax seems to be always ESM?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah but then dont see how it can ever be enabled by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could take the same approach as syntax detection: try to run as regular --eval, if it throws based on an exception that might’ve been caused by TypeScript syntax, retry as --input-type=strip-types.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes thats what Im experimenting


### `--experimental-strip-types`

<!-- YAML
Expand Down Expand Up @@ -3054,6 +3066,7 @@ one is included in the list below.
* `--experimental-require-module`
* `--experimental-shadow-realm`
* `--experimental-specifier-resolution`
* `--experimental-strip-input-types`
* `--experimental-strip-types`
* `--experimental-top-level-await`
* `--experimental-transform-types`
Expand Down
3 changes: 2 additions & 1 deletion doc/api/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ import { fn, FnParams } from './fn.ts';

### Non-file forms of input

Type stripping can be enabled for `--eval`. The module system
Type stripping can be enabled for `--eval` by using the flag [`--experimental-strip-input-types`][]. The module system
will be determined by `--input-type`, as it is for JavaScript.

TypeScript syntax is unsupported in the REPL, STDIN input, `--print`, `--check`, and
Expand Down Expand Up @@ -181,6 +181,7 @@ with `#`.
[CommonJS]: modules.md
[ES Modules]: esm.md
[Full TypeScript support]: #full-typescript-support
[`--experimental-strip-input-types`]: cli.md#--experimental-strip-input-types
[`--experimental-strip-types`]: cli.md#--experimental-strip-types
[`--experimental-transform-types`]: cli.md#--experimental-transform-types
[`tsconfig` "paths"]: https://www.typescriptlang.org/tsconfig/#paths
Expand Down
3 changes: 3 additions & 0 deletions doc/node.1
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ Configures the type of test isolation used in the test runner.
.It Fl -experimental-test-module-mocks
Enable module mocking in the test runner.
.
.It Fl -experimental-strip-input-types
Enable experimental type-stripping for eval input.
.
.It Fl -experimental-strip-types
Enable experimental type-stripping for TypeScript files.
.
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/main/eval_string.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ addBuiltinLibsToObject(globalThis, '<eval>');
markBootstrapComplete();

const code = getOptionValue('--eval');
const source = getOptionValue('--experimental-strip-types') ?
const source = getOptionValue('--experimental-strip-input-types') ?
stripTypeScriptModuleTypes(code) :
code;

Expand Down
1 change: 0 additions & 1 deletion lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ function initializeCJS() {

const tsEnabled = getOptionValue('--experimental-strip-types');
if (tsEnabled) {
emitExperimentalWarning('Type Stripping');
Module._extensions['.cts'] = loadCTS;
Module._extensions['.ts'] = loadTS;
}
Expand Down
3 changes: 0 additions & 3 deletions lib/internal/modules/esm/translators.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ translators.set('require-commonjs', (url, source, isMain) => {
// Handle CommonJS modules referenced by `require` calls.
// This translator function must be sync, as `require` is sync.
translators.set('require-commonjs-typescript', (url, source, isMain) => {
emitExperimentalWarning('Type Stripping');
assert(cjsParse);
const code = stripTypeScriptModuleTypes(stringify(source), url);
return createCJSModuleWrap(url, code, isMain, 'commonjs-typescript');
Expand Down Expand Up @@ -464,7 +463,6 @@ translators.set('wasm', async function(url, source) {

// Strategy for loading a commonjs TypeScript module
translators.set('commonjs-typescript', function(url, source) {
emitExperimentalWarning('Type Stripping');
assertBufferSource(source, true, 'load');
const code = stripTypeScriptModuleTypes(stringify(source), url);
debug(`Translating TypeScript ${url}`);
Expand All @@ -473,7 +471,6 @@ translators.set('commonjs-typescript', function(url, source) {

// Strategy for loading an esm TypeScript module
translators.set('module-typescript', function(url, source) {
emitExperimentalWarning('Type Stripping');
assertBufferSource(source, true, 'load');
const code = stripTypeScriptModuleTypes(stringify(source), url);
debug(`Translating TypeScript ${url}`);
Expand Down
1 change: 1 addition & 0 deletions lib/internal/modules/typescript.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ function processTypeScriptCode(code, options) {
* @returns {TransformOutput} The stripped TypeScript code.
*/
function stripTypeScriptModuleTypes(source, filename) {
emitExperimentalWarning('Type Stripping');
assert(typeof source === 'string');
if (isUnderNodeModules(filename)) {
throw new ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING(filename);
Expand Down
5 changes: 5 additions & 0 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"ES module to preload (option can be repeated)",
&EnvironmentOptions::preload_esm_modules,
kAllowedInEnvvar);
AddOption("--experimental-strip-input-types",
"Experimental type-stripping for eval",
&EnvironmentOptions::experimental_strip_input_types,
kAllowedInEnvvar);
AddOption("--experimental-strip-types",
"Experimental type-stripping for TypeScript files.",
&EnvironmentOptions::experimental_strip_types,
Expand All @@ -855,6 +859,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
kAllowedInEnvvar);
Implies("--experimental-transform-types", "--experimental-strip-types");
Implies("--experimental-transform-types", "--enable-source-maps");
Implies("--experimental-strip-input-types", "--experimental-strip-types");
AddOption("--interactive",
"always enter the REPL even if stdin does not appear "
"to be a terminal",
Expand Down
1 change: 1 addition & 0 deletions src/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ class EnvironmentOptions : public Options {
std::vector<std::string> preload_esm_modules;

bool experimental_strip_types = false;
bool experimental_strip_input_types = false;
bool experimental_transform_types = false;

std::vector<std::string> user_argv;
Expand Down
32 changes: 23 additions & 9 deletions test/es-module/test-typescript-eval.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if (!process.config.variables.node_use_amaro) skip('Requires Amaro');

test('eval TypeScript ESM syntax', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--eval',
`import util from 'node:util'
const text: string = 'Hello, TypeScript!'
Expand All @@ -19,7 +19,7 @@ test('eval TypeScript ESM syntax', async () => {

test('eval TypeScript ESM syntax with input-type module', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--input-type=module',
'--eval',
`import util from 'node:util'
Expand All @@ -33,7 +33,7 @@ test('eval TypeScript ESM syntax with input-type module', async () => {

test('eval TypeScript CommonJS syntax', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--eval',
`const util = require('node:util');
const text: string = 'Hello, TypeScript!'
Expand All @@ -46,7 +46,7 @@ test('eval TypeScript CommonJS syntax', async () => {

test('eval TypeScript CommonJS syntax with input-type commonjs', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--input-type=commonjs',
'--eval',
`const util = require('node:util');
Expand All @@ -60,7 +60,7 @@ test('eval TypeScript CommonJS syntax with input-type commonjs', async () => {

test('eval TypeScript CommonJS syntax by default', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--eval',
`const util = require('node:util');
const text: string = 'Hello, TypeScript!'
Expand All @@ -74,7 +74,7 @@ test('eval TypeScript CommonJS syntax by default', async () => {

test('TypeScript ESM syntax not specified', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--eval',
`import util from 'node:util'
const text: string = 'Hello, TypeScript!'
Expand All @@ -86,7 +86,7 @@ test('TypeScript ESM syntax not specified', async () => {

test('expect fail eval TypeScript CommonJS syntax with input-type module', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--input-type=module',
'--eval',
`const util = require('node:util');
Expand All @@ -100,7 +100,7 @@ test('expect fail eval TypeScript CommonJS syntax with input-type module', async

test('expect fail eval TypeScript ESM syntax with input-type commonjs', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--input-type=commonjs',
'--eval',
`import util from 'node:util'
Expand All @@ -113,10 +113,24 @@ test('expect fail eval TypeScript ESM syntax with input-type commonjs', async ()

test('check syntax error is thrown when passing invalid syntax', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--experimental-strip-input-types',
'--eval',
'enum Foo { A, B, C }']);
strictEqual(result.stdout, '');
match(result.stderr, /ERR_INVALID_TYPESCRIPT_SYNTAX/);
strictEqual(result.code, 1);
});

test('eval TypeScript without --experimental-strip-input-types but --experimental-strip-types', async () => {
const result = await spawnPromisified(process.execPath, [
'--experimental-strip-types',
'--input-type=module',
'--eval',
`import util from 'node:util'
const text: string = 'Hello, TypeScript!'
console.log(util.styleText('red', text));`]);

match(result.stderr, /SyntaxError: Missing initializer in const declaration/);
strictEqual(result.stdout, '');
strictEqual(result.code, 1);
});
Loading