Skip to content

fix(kotlin): preserve enum string values in --just-types mode#3007

Merged
schani merged 1 commit into
masterfrom
agent/fix-issue-1601
Jul 21, 2026
Merged

fix(kotlin): preserve enum string values in --just-types mode#3007
schani merged 1 commit into
masterfrom
agent/fix-issue-1601

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Bug

Kotlin --just-types output dropped the original string value associated
with each enum case. Given:

export enum CanvasAction {
  ADD = 'add',
  BRING_TO_FRONT = 'bringtofront',
  ...
}

quicktype --lang kotlin --just-types produced:

enum class CanvasAction {
    Add,
    Bringtofront,
    ...
}

with no way to recover which JSON string ("add", "bringtofront", ...)
each case originally corresponded to.

Root cause

Kotlin's base KotlinRenderer (used by --just-types mode) had its own
emitEnumDefinition that emitted a bare enum class with no value
information. Every other Kotlin framework — Klaxon, Jackson, and kotlinx —
overrides emitEnumDefinition and does preserve the value via a
value: String constructor arg plus a fromValue/toValue mapping. Java's
--just-types mode also preserves the value (via toValue()/forValue()),
without depending on any JSON library. So Kotlin --just-types was the
outlier, silently losing information other modes and other languages
already keep.

Fix

KotlinRenderer.emitEnumDefinition now emits each case with its original
(escaped) string value as a constructor argument, plus a framework-independent
companion object with a fromValue(value: String): EnumName lookup —
consistent with the shape already used by the other Kotlin renderers, but
with no dependency on any JSON library (as required for --just-types
mode):

enum class CanvasAction(val value: String) {
    Add("add"),
    Bringtofront("bringtofront"),
    ...;

    companion object {
        fun fromValue(value: String): CanvasAction = when (value) {
            "add"          -> Add
            "bringtofront" -> Bringtofront
            ...
            else           -> throw IllegalArgumentException()
        }
    }
}

Test coverage

Added a regression test to test/unit/just-types-option.test.ts that
generates Kotlin --just-types output from the exact TypeScript enum from
the issue report and asserts the case constructors carry their original
string values and that a fromValue lookup is emitted. The test was
confirmed to fail against the unfixed renderer and pass after the fix.

A unit test (rather than a JSON/JSON Schema fixture) was used because there
is no existing compile-and-run fixture for Kotlin --just-types mode (that
mode has no serialization to round-trip, which appears to be why one was
never set up for it), matching the precedent already established by the
other --just-types assertions in that same test file.

Verification

  • npm run build — passes.
  • npm run test:unit — 164/164 tests pass.
  • Manually re-ran the exact repro from the issue
    (node dist/index.js --lang kotlin --just-types canvas.ts) and confirmed
    the generated output now preserves the enum values.
  • The Kotlin compiler toolchain (kotlinc) is not available in this
    environment, so the compile-and-run Kotlin fixtures (Klaxon, Jackson,
    kotlinx) could not be executed locally. This change only modifies
    KotlinRenderer.emitEnumDefinition, which every one of those three
    frameworks overrides with its own implementation, so it should have no
    effect on their generated output; CI will validate this.

Fixes #1601

🤖 Generated with Claude Code

Kotlin's base renderer (used by --just-types) emitted bare enum
constants, dropping the original JSON string associated with each
case. Every other Kotlin framework (Klaxon, Jackson, kotlinx) and
Java's --just-types already preserve this value, making --just-types
Kotlin enums an inconsistent, lossy outlier.

Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
@schani
schani merged commit bbf2d6e into master Jul 21, 2026
28 checks passed
@schani
schani deleted the agent/fix-issue-1601 branch July 21, 2026 13:38
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.

Enum value is lost in the Typescript to Kotlin - Just Types conversation.

1 participant