@@ -97,6 +97,7 @@ const {
9797 decorateErrorStack,
9898 isError,
9999 deprecate,
100+ getLazy,
100101 SideEffectFreeRegExpPrototypeSymbolReplace,
101102 SideEffectFreeRegExpPrototypeSymbolSplit,
102103} = require ( 'internal/util' ) ;
@@ -141,6 +142,9 @@ const {
141142const experimentalREPLAwait = getOptionValue (
142143 '--experimental-repl-await' ,
143144) ;
145+ const experimentalREPLTypeScript = getOptionValue (
146+ '--experimental-repl-typescript'
147+ )
144148const pendingDeprecation = getOptionValue ( '--pending-deprecation' ) ;
145149const {
146150 REPL_MODE_SLOPPY ,
@@ -177,8 +181,12 @@ const {
177181
178182// Lazy-loaded.
179183let processTopLevelAwait ;
184+ const processTypeScriptCode = getLazy ( ( ) => require ( 'internal/modules/typescript' ) . processTypeScriptCode ) ;
185+ const checkSyntax = getLazy ( ( ) => require ( 'internal/main/check_syntax' ) . checkSyntax ) ;
180186
181187const parentModule = module ;
188+ const kREPLTag = '[repl]' ;
189+ const kTypeScriptOptions = { __proto__ : null , mode : 'strip-only' , filename : kREPLTag } ;
182190
183191// AsyncLocalStorage to track which REPL instance owns the current async context
184192// This replaces the domain-based tracking for error handling
@@ -477,6 +485,41 @@ class REPLServer extends Interface {
477485 phase === 'evaluation' ? cascadedLoader . kEvaluationPhase :
478486 cascadedLoader . kSourcePhase ) ;
479487 }
488+ function runScript ( scriptCode ) {
489+ if ( experimentalREPLTypeScript ) {
490+ try {
491+ // Try parsing as pure JS
492+ checkSyntax ( ) ( scriptCode , kREPLTag ) ;
493+ } catch ( originalError ) {
494+ try {
495+ // That failed, so try stripping TypeScript types
496+ scriptCode = processTypeScriptCode ( ) ( scriptCode , kTypeScriptOptions ) ;
497+ } catch ( tsError ) {
498+ // If it's invalid or unsupported TypeScript syntax, rethrow the original error
499+ // with the TypeScript error message added to the stack.
500+ if ( tsError . code === 'ERR_INVALID_TYPESCRIPT_SYNTAX' ||
501+ tsError . code === 'ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX' ) {
502+ originalError . stack = `${ tsError . message } \n\n${ originalError . stack } ` ;
503+ throw originalError ;
504+ }
505+
506+ throw tsError ;
507+ }
508+ }
509+ }
510+
511+ return makeContextifyScript (
512+ scriptCode , // code
513+ file , // filename,
514+ 0 , // lineOffset
515+ 0 , // columnOffset,
516+ undefined , // cachedData
517+ false , // produceCachedData
518+ undefined , // parsingContext
519+ hostDefinedOptionId , // hostDefinedOptionId
520+ importModuleDynamically , // importModuleDynamically
521+ ) ;
522+ }
480523 // `experimentalREPLAwait` is set to true by default.
481524 // Shall be false in case `--no-experimental-repl-await` flag is used.
482525 if ( experimentalREPLAwait && StringPrototypeIncludes ( code , 'await' ) ) {
@@ -498,17 +541,7 @@ class REPLServer extends Interface {
498541 // in order to detect if error is truly non recoverable
499542 const fallbackCode = SideEffectFreeRegExpPrototypeSymbolReplace ( / \b a w a i t \b / g, code , '' ) ;
500543 try {
501- makeContextifyScript (
502- fallbackCode , // code
503- file , // filename,
504- 0 , // lineOffset
505- 0 , // columnOffset,
506- undefined , // cachedData
507- false , // produceCachedData
508- undefined , // parsingContext
509- hostDefinedOptionId , // hostDefinedOptionId
510- importModuleDynamically , // importModuleDynamically
511- ) ;
544+ runScript ( fallbackCode ) ;
512545 } catch ( fallbackError ) {
513546 if ( isRecoverableError ( fallbackError , fallbackCode ) ) {
514547 recoverableError = true ;
@@ -536,17 +569,7 @@ class REPLServer extends Interface {
536569 // value for statements and declarations that don't return a value.
537570 code = `'use strict'; void 0;\n${ code } ` ;
538571 }
539- script = makeContextifyScript (
540- code , // code
541- file , // filename,
542- 0 , // lineOffset
543- 0 , // columnOffset,
544- undefined , // cachedData
545- false , // produceCachedData
546- undefined , // parsingContext
547- hostDefinedOptionId , // hostDefinedOptionId
548- importModuleDynamically , // importModuleDynamically
549- ) ;
572+ script = runScript ( code ) ;
550573 } catch ( e ) {
551574 debug ( 'parse error %j' , code , e ) ;
552575 if ( wrappedCmd ) {
0 commit comments