Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 22, 2026

--showConfig was printing raw integer values for enum options (e.g., "moduleDetection": 3) instead of their string names ("moduleDetection": "force").

Changes

Added MarshalJSON() methods to compiler option enum types:

  • compileroptions.go: JsxEmit, ScriptTarget, ModuleKind, ModuleResolutionKind, ModuleDetectionKind, NewLineKind
  • watchoptions.go: WatchFileKind, WatchDirectoryKind, PollingKind

Before/After

 {
-    "jsx": 3,
-    "module": 99,
-    "moduleDetection": 3,
-    "target": 7
+    "jsx": "react",
+    "module": "esnext",
+    "moduleDetection": "force",
+    "target": "es2020"
 }
Original prompt

Fix --showConfig to print enumerated value names, not integers

e.g.

> tsgo --showconfig
[... others]
    "moduleDetection": 3,

We should see the symbol name (I believe this one is "force"?), not "3" on the last line

Backcompat is not a concern and you don't need to handle parsing this as an input format; this is only a bug in showConfig


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix showConfig to print enumerated value names Fix --showConfig to print enumerated value names, not integers Jan 22, 2026
Copilot AI requested a review from RyanCavanaugh January 22, 2026 20:38
@RyanCavanaugh RyanCavanaugh marked this pull request as ready for review January 22, 2026 21:38
Copilot AI review requested due to automatic review settings January 22, 2026 21:38
@jakebailey
Copy link
Member

Is this not exactly the same as #2570?

There are no tests (CLI tests for --showConfig should be very easy), and these methods will affect tsbuildinfo, so it must not have run the tests?

@jakebailey
Copy link
Member

jakebailey commented Jan 22, 2026

Honestly, I think this approach is hopeless. This won't handle implied options like the old code.

I think that we need to port the old code, but adapt it to work more similarly to --init, using the compiler options declarations, reflect, etc, and not even use the JSON packages.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates JSON serialization for several compiler and watch option enums so that --showConfig outputs human-readable enum names (e.g. "moduleDetection": "force") instead of raw integer values (e.g. "moduleDetection": 3).

Changes:

  • Added MarshalJSON implementations for JsxEmit, ScriptTarget, ModuleKind, ModuleResolutionKind, ModuleDetectionKind, and NewLineKind in compileroptions.go to emit string names (or null for unset/sentinel values).
  • Added MarshalJSON implementations for WatchFileKind, WatchDirectoryKind, and PollingKind in watchoptions.go to emit string names (or null) for watch-related options.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
internal/core/compileroptions.go Adds custom JSON marshaling for core compiler option enums so they serialize to descriptive strings instead of integers.
internal/core/watchoptions.go Adds custom JSON marshaling for watch-related enums so watch options can also serialize to descriptive strings.

Comment on lines +544 to +596
func (j JsxEmit) MarshalJSON() ([]byte, error) {
switch j {
case JsxEmitNone:
return []byte("null"), nil
case JsxEmitPreserve:
return []byte(`"preserve"`), nil
case JsxEmitReactNative:
return []byte(`"react-native"`), nil
case JsxEmitReact:
return []byte(`"react"`), nil
case JsxEmitReactJSX:
return []byte(`"react-jsx"`), nil
case JsxEmitReactJSXDev:
return []byte(`"react-jsxdev"`), nil
default:
return []byte("null"), nil
}
}

func (s ScriptTarget) MarshalJSON() ([]byte, error) {
switch s {
case ScriptTargetNone:
return []byte("null"), nil
case ScriptTargetES5:
return []byte(`"es5"`), nil
case ScriptTargetES2015:
return []byte(`"es2015"`), nil
case ScriptTargetES2016:
return []byte(`"es2016"`), nil
case ScriptTargetES2017:
return []byte(`"es2017"`), nil
case ScriptTargetES2018:
return []byte(`"es2018"`), nil
case ScriptTargetES2019:
return []byte(`"es2019"`), nil
case ScriptTargetES2020:
return []byte(`"es2020"`), nil
case ScriptTargetES2021:
return []byte(`"es2021"`), nil
case ScriptTargetES2022:
return []byte(`"es2022"`), nil
case ScriptTargetES2023:
return []byte(`"es2023"`), nil
case ScriptTargetES2024:
return []byte(`"es2024"`), nil
case ScriptTargetESNext:
return []byte(`"esnext"`), nil
case ScriptTargetJSON:
return []byte(`"json"`), nil
default:
return []byte("null"), nil
}
}
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

These new MarshalJSON implementations for the enum fields (JsxEmit/ScriptTarget/ModuleKind/ModuleResolutionKind/ModuleDetectionKind/NewLineKind) change the JSON shape of core.CompilerOptions from numeric enum values to strings, but there are existing tests that round-trip CompilerOptions through json.Marshal/json.Unmarshal (e.g. internal/tsoptions/commandlineparser_test.go:225–229 and 331–334). Since these enum types do not implement UnmarshalJSON, json.Unmarshal will still expect numeric JSON tokens for these int32-backed fields, so it will fail (or at least diverge from the TypeScript baselines) when given the new string values like "react" or "es2020". To keep the tests and any other JSON consumers working, consider either (a) adding matching UnmarshalJSON implementations for these enum types that accept the same string representations, or (b) leaving the default JSON for core.CompilerOptions as numeric and instead introducing a dedicated DTO or adapter used only by --showConfig that serializes enum values as strings.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants