@@ -44,7 +44,6 @@ import {
4444 filterMutate ,
4545 find ,
4646 findIndex ,
47- firstOrUndefinedIterator ,
4847 flatten ,
4948 forEach ,
5049 forEachEntry ,
@@ -249,6 +248,7 @@ const libEntries: [string, string][] = [
249248 [ "esnext.iterator" , "lib.esnext.iterator.d.ts" ] ,
250249 [ "esnext.promise" , "lib.esnext.promise.d.ts" ] ,
251250 [ "esnext.float16" , "lib.esnext.float16.d.ts" ] ,
251+ [ "esnext.error" , "lib.esnext.error.d.ts" ] ,
252252 [ "decorators" , "lib.decorators.d.ts" ] ,
253253 [ "decorators.legacy" , "lib.decorators.legacy.d.ts" ] ,
254254] ;
@@ -2789,140 +2789,146 @@ function serializeOptionBaseObject(
27892789 return result ;
27902790}
27912791
2792- /**
2793- * Generate a list of the compiler options whose value is not the default.
2794- * @param options compilerOptions to be evaluated.
2795- /** @internal */
2796- export function getCompilerOptionsDiffValue ( options : CompilerOptions , newLine : string ) : string {
2797- const compilerOptionsMap = getSerializedCompilerOption ( options ) ;
2798- return getOverwrittenDefaultOptions ( ) ;
2799-
2800- function makePadding ( paddingLength : number ) : string {
2801- return Array ( paddingLength + 1 ) . join ( " " ) ;
2802- }
2803-
2804- function getOverwrittenDefaultOptions ( ) {
2805- const result : string [ ] = [ ] ;
2806- const tab = makePadding ( 2 ) ;
2807- commandOptionsWithoutBuild . forEach ( cmd => {
2808- if ( ! compilerOptionsMap . has ( cmd . name ) ) {
2809- return ;
2810- }
2811-
2812- const newValue = compilerOptionsMap . get ( cmd . name ) ;
2813- const defaultValue = getDefaultValueForOption ( cmd ) ;
2814- if ( newValue !== defaultValue ) {
2815- result . push ( `${ tab } ${ cmd . name } : ${ newValue } ` ) ;
2816- }
2817- else if ( hasProperty ( defaultInitCompilerOptions , cmd . name ) ) {
2818- result . push ( `${ tab } ${ cmd . name } : ${ defaultValue } ` ) ;
2819- }
2820- } ) ;
2821- return result . join ( newLine ) + newLine ;
2822- }
2823- }
2824-
2825- /**
2826- * Get the compiler options to be written into the tsconfig.json.
2827- * @param options commandlineOptions to be included in the compileOptions.
2828- */
2829- function getSerializedCompilerOption ( options : CompilerOptions ) : Map < string , CompilerOptionsValue > {
2830- const compilerOptions = extend ( options , defaultInitCompilerOptions ) ;
2831- return serializeCompilerOptions ( compilerOptions ) ;
2832- }
28332792/**
28342793 * Generate tsconfig configuration when running command line "--init"
28352794 * @param options commandlineOptions to be generated into tsconfig.json
2836- * @param fileNames array of filenames to be generated into tsconfig.json
2837- *
28382795 * @internal
28392796 */
2840- export function generateTSConfig ( options : CompilerOptions , fileNames : readonly string [ ] , newLine : string ) : string {
2841- const compilerOptionsMap = getSerializedCompilerOption ( options ) ;
2842- return writeConfigurations ( ) ;
2797+ export function generateTSConfig ( options : CompilerOptions , newLine : string ) : string {
2798+ type PresetValue = string | number | boolean | ( string | number | boolean ) [ ] ;
2799+
2800+ const tab = " " ;
2801+ const result : string [ ] = [ ] ;
2802+ const allSetOptions = Object . keys ( options ) . filter ( k => k !== "init" && k !== "help" && k !== "watch" ) ;
2803+
2804+ result . push ( `{` ) ;
2805+ result . push ( `${ tab } // ${ getLocaleSpecificMessage ( Diagnostics . Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_to_read_more_about_this_file ) } ` ) ;
2806+ result . push ( `${ tab } "compilerOptions": {` ) ;
2807+
2808+ emitHeader ( Diagnostics . File_Layout ) ;
2809+ emitOption ( "rootDir" , "./src" , "optional" ) ;
2810+ emitOption ( "outDir" , "./dist" , "optional" ) ;
2811+
2812+ newline ( ) ;
2813+
2814+ emitHeader ( Diagnostics . Environment_Settings ) ;
2815+ emitHeader ( Diagnostics . See_also_https_Colon_Slash_Slashaka_ms_Slashtsconfig_Slashmodule ) ;
2816+ emitOption ( "module" , ModuleKind . NodeNext ) ;
2817+ emitOption ( "target" , ScriptTarget . ESNext ) ;
2818+ emitOption ( "types" , [ ] ) ;
2819+ if ( options . lib ) {
2820+ emitOption ( "lib" , options . lib ) ;
2821+ }
2822+ emitHeader ( Diagnostics . For_nodejs_Colon ) ;
2823+ result . push ( `${ tab } ${ tab } // "lib": ["esnext"],` ) ;
2824+ result . push ( `${ tab } ${ tab } // "types": ["node"],` ) ;
2825+ emitHeader ( Diagnostics . and_npm_install_D_types_Slashnode ) ;
2826+
2827+ newline ( ) ;
2828+
2829+ emitHeader ( Diagnostics . Other_Outputs ) ;
2830+ emitOption ( "sourceMap" , /*defaultValue*/ true ) ;
2831+ emitOption ( "declaration" , /*defaultValue*/ true ) ;
2832+ emitOption ( "declarationMap" , /*defaultValue*/ true ) ;
2833+
2834+ newline ( ) ;
2835+
2836+ emitHeader ( Diagnostics . Stricter_Typechecking_Options ) ;
2837+ emitOption ( "noUncheckedIndexedAccess" , /*defaultValue*/ true ) ;
2838+ emitOption ( "exactOptionalPropertyTypes" , /*defaultValue*/ true ) ;
2839+
2840+ newline ( ) ;
2841+
2842+ emitHeader ( Diagnostics . Style_Options ) ;
2843+ emitOption ( "noImplicitReturns" , /*defaultValue*/ true , "optional" ) ;
2844+ emitOption ( "noImplicitOverride" , /*defaultValue*/ true , "optional" ) ;
2845+ emitOption ( "noUnusedLocals" , /*defaultValue*/ true , "optional" ) ;
2846+ emitOption ( "noUnusedParameters" , /*defaultValue*/ true , "optional" ) ;
2847+ emitOption ( "noFallthroughCasesInSwitch" , /*defaultValue*/ true , "optional" ) ;
2848+ emitOption ( "noPropertyAccessFromIndexSignature" , /*defaultValue*/ true , "optional" ) ;
2849+
2850+ newline ( ) ;
2851+
2852+ emitHeader ( Diagnostics . Recommended_Options ) ;
2853+ emitOption ( "strict" , /*defaultValue*/ true ) ;
2854+ emitOption ( "jsx" , JsxEmit . ReactJSX ) ;
2855+ emitOption ( "verbatimModuleSyntax" , /*defaultValue*/ true ) ;
2856+ emitOption ( "isolatedModules" , /*defaultValue*/ true ) ;
2857+ emitOption ( "noUncheckedSideEffectImports" , /*defaultValue*/ true ) ;
2858+ emitOption ( "moduleDetection" , ModuleDetectionKind . Force ) ;
2859+ emitOption ( "skipLibCheck" , /*defaultValue*/ true ) ;
2860+
2861+ // Write any user-provided options we haven't already
2862+ if ( allSetOptions . length > 0 ) {
2863+ newline ( ) ;
2864+ while ( allSetOptions . length > 0 ) {
2865+ emitOption ( allSetOptions [ 0 ] , options [ allSetOptions [ 0 ] ] ) ;
2866+ }
2867+ }
28432868
2844- function makePadding ( paddingLength : number ) : string {
2845- return Array ( paddingLength + 1 ) . join ( " ") ;
2869+ function newline ( ) {
2870+ result . push ( " ") ;
28462871 }
28472872
2848- function isAllowedOptionForOutput ( { category, name, isCommandLineOnly } : CommandLineOption ) : boolean {
2849- // Skip options which do not have a category or have categories which are more niche
2850- const categoriesToSkip = [ Diagnostics . Command_line_Options , Diagnostics . Editor_Support , Diagnostics . Compiler_Diagnostics , Diagnostics . Backwards_Compatibility , Diagnostics . Watch_and_Build_Modes , Diagnostics . Output_Formatting ] ;
2851- return ! isCommandLineOnly && category !== undefined && ( ! categoriesToSkip . includes ( category ) || compilerOptionsMap . has ( name ) ) ;
2873+ function emitHeader ( header : DiagnosticMessage ) {
2874+ result . push ( `${ tab } ${ tab } // ${ getLocaleSpecificMessage ( header ) } ` ) ;
28522875 }
28532876
2854- function writeConfigurations ( ) {
2855- // Filter applicable options to place in the file
2856- const categorizedOptions = new Map < DiagnosticMessage , CommandLineOption [ ] > ( ) ;
2857- // Set allowed categories in order
2858- categorizedOptions . set ( Diagnostics . Projects , [ ] ) ;
2859- categorizedOptions . set ( Diagnostics . Language_and_Environment , [ ] ) ;
2860- categorizedOptions . set ( Diagnostics . Modules , [ ] ) ;
2861- categorizedOptions . set ( Diagnostics . JavaScript_Support , [ ] ) ;
2862- categorizedOptions . set ( Diagnostics . Emit , [ ] ) ;
2863- categorizedOptions . set ( Diagnostics . Interop_Constraints , [ ] ) ;
2864- categorizedOptions . set ( Diagnostics . Type_Checking , [ ] ) ;
2865- categorizedOptions . set ( Diagnostics . Completeness , [ ] ) ;
2866- for ( const option of optionDeclarations ) {
2867- if ( isAllowedOptionForOutput ( option ) ) {
2868- let listForCategory = categorizedOptions . get ( option . category ! ) ;
2869- if ( ! listForCategory ) categorizedOptions . set ( option . category ! , listForCategory = [ ] ) ;
2870- listForCategory . push ( option ) ;
2871- }
2877+ // commented = 'always': Always comment this out, even if it's on commandline
2878+ // commented = 'optional': Comment out unless it's on commandline
2879+ // commented = 'never': Never comment this out
2880+ function emitOption < K extends string & keyof CompilerOptions > ( setting : K , defaultValue : CompilerOptions [ K ] , commented : "always" | "optional" | "never" = "never" ) {
2881+ const existingOptionIndex = allSetOptions . indexOf ( setting ) ;
2882+ if ( existingOptionIndex >= 0 ) {
2883+ allSetOptions . splice ( existingOptionIndex , 1 ) ;
28722884 }
28732885
2874- // Serialize all options and their descriptions
2875- let marginLength = 0 ;
2876- let seenKnownKeys = 0 ;
2877- const entries : { value : string ; description ?: string ; } [ ] = [ ] ;
2878- categorizedOptions . forEach ( ( options , category ) => {
2879- if ( entries . length !== 0 ) {
2880- entries . push ( { value : "" } ) ;
2881- }
2882- entries . push ( { value : `/* ${ getLocaleSpecificMessage ( category ) } */` } ) ;
2883- for ( const option of options ) {
2884- let optionName ;
2885- if ( compilerOptionsMap . has ( option . name ) ) {
2886- optionName = `"${ option . name } ": ${ JSON . stringify ( compilerOptionsMap . get ( option . name ) ) } ${ ( seenKnownKeys += 1 ) === compilerOptionsMap . size ? "" : "," } ` ;
2887- }
2888- else {
2889- optionName = `// "${ option . name } ": ${ JSON . stringify ( getDefaultValueForOption ( option ) ) } ,` ;
2890- }
2891- entries . push ( {
2892- value : optionName ,
2893- description : `/* ${ option . description && getLocaleSpecificMessage ( option . description ) || option . name } */` ,
2894- } ) ;
2895- marginLength = Math . max ( optionName . length , marginLength ) ;
2896- }
2897- } ) ;
2898-
2899- // Write the output
2900- const tab = makePadding ( 2 ) ;
2901- const result : string [ ] = [ ] ;
2902- result . push ( `{` ) ;
2903- result . push ( `${ tab } "compilerOptions": {` ) ;
2904- result . push ( `${ tab } ${ tab } /* ${ getLocaleSpecificMessage ( Diagnostics . Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_to_read_more_about_this_file ) } */` ) ;
2905- result . push ( "" ) ;
2906- // Print out each row, aligning all the descriptions on the same column.
2907- for ( const entry of entries ) {
2908- const { value, description = "" } = entry ;
2909- result . push ( value && `${ tab } ${ tab } ${ value } ${ description && ( makePadding ( marginLength - value . length + 2 ) + description ) } ` ) ;
2886+ let comment : boolean ;
2887+ if ( commented === "always" ) {
2888+ comment = true ;
29102889 }
2911- if ( fileNames . length ) {
2912- result . push ( `${ tab } },` ) ;
2913- result . push ( `${ tab } "files": [` ) ;
2914- for ( let i = 0 ; i < fileNames . length ; i ++ ) {
2915- result . push ( `${ tab } ${ tab } ${ JSON . stringify ( fileNames [ i ] ) } ${ i === fileNames . length - 1 ? "" : "," } ` ) ;
2916- }
2917- result . push ( `${ tab } ]` ) ;
2890+ else if ( commented === "never" ) {
2891+ comment = false ;
29182892 }
29192893 else {
2920- result . push ( ` ${ tab } }` ) ;
2894+ comment = ! hasProperty ( options , setting ) ;
29212895 }
2922- result . push ( `}` ) ;
29232896
2924- return result . join ( newLine ) + newLine ;
2897+ const value = ( options [ setting ] ?? defaultValue ) as PresetValue ;
2898+ if ( comment ) {
2899+ result . push ( `${ tab } ${ tab } // "${ setting } ": ${ formatValueOrArray ( setting , value ) } ,` ) ;
2900+ }
2901+ else {
2902+ result . push ( `${ tab } ${ tab } "${ setting } ": ${ formatValueOrArray ( setting , value ) } ,` ) ;
2903+ }
29252904 }
2905+
2906+ function formatValueOrArray ( settingName : string , value : PresetValue ) : string {
2907+ const option = optionDeclarations . filter ( c => c . name === settingName ) [ 0 ] ;
2908+ if ( ! option ) Debug . fail ( `No option named ${ settingName } ?` ) ;
2909+ const map = ( option . type instanceof Map ) ? option . type : undefined ;
2910+ if ( isArray ( value ) ) {
2911+ // eslint-disable-next-line local/no-in-operator
2912+ const map = ( "element" in option && ( option . element . type instanceof Map ) ) ? option . element . type : undefined ;
2913+ return `[${ value . map ( v => formatSingleValue ( v , map ) ) . join ( ", " ) } ]` ;
2914+ }
2915+ else {
2916+ return formatSingleValue ( value , map ) ;
2917+ }
2918+ }
2919+
2920+ function formatSingleValue ( value : PresetValue , map : Map < string , string | number > | undefined ) {
2921+ if ( map ) {
2922+ value = getNameOfCompilerOptionValue ( value as string | number , map ) ?? Debug . fail ( `No matching value of ${ value } ` ) ;
2923+ }
2924+ return JSON . stringify ( value ) ;
2925+ }
2926+
2927+ result . push ( `${ tab } }` ) ;
2928+ result . push ( `}` ) ;
2929+ result . push ( `` ) ;
2930+
2931+ return result . join ( newLine ) ;
29262932}
29272933
29282934/** @internal */
@@ -4256,25 +4262,3 @@ function getOptionValueWithEmptyStrings(value: any, option: CommandLineOption):
42564262 } ) ;
42574263 }
42584264}
4259-
4260- function getDefaultValueForOption ( option : CommandLineOption ) : { } {
4261- switch ( option . type ) {
4262- case "number" :
4263- return 1 ;
4264- case "boolean" :
4265- return true ;
4266- case "string" :
4267- const defaultValue = option . defaultValueDescription ;
4268- return option . isFilePath ? `./${ defaultValue && typeof defaultValue === "string" ? defaultValue : "" } ` : "" ;
4269- case "list" :
4270- return [ ] ;
4271- case "listOrElement" :
4272- return getDefaultValueForOption ( option . element ) ;
4273- case "object" :
4274- return { } ;
4275- default :
4276- const value = firstOrUndefinedIterator ( option . type . keys ( ) ) ;
4277- if ( value !== undefined ) return value ;
4278- return Debug . fail ( "Expected 'option.type' to have entries." ) ;
4279- }
4280- }
0 commit comments