Class ENUMs incorrectly output as union type when using mapEnum asEnum
Opened this issue · 1 comments
garbit commented
Hi there,
I have a kotlin enum in my data class file that seems to output a string union type in my TS implementation file as well as an enum definition. I was expecting my interface to use the enum rather than the string union type. How can I configure the typescript generation step to achieve this?
Enum:
import com.fasterxml.jackson.annotation.JsonValue
enum class ContentItemType(
@JsonValue
val id: Int,
val pathPrefix: String
) {
THING(id = 0, pathPrefix = "content_thing"),
companion object {
fun fromId(id: Int): ContentItemType {
return entries.find { it.id == id } ?: THING
}
}
}
Class:
import java.util.*
data class ThingContentItem(
override val type: ContentItemType = ContentItemType.THING,
val title: String,
): DataContentItem
DataContentItem
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "type"
)
@JsonSubTypes(
value = [
JsonSubTypes.Type(value = ThingContentItemDto::class, name = "0"),
]
)
sealed interface DataContentItem {
val type: ContentItemType
}
I use the following settings in my gradle file:
tasks {
generateTypeScript {
jsonLibrary = JsonLibrary.jackson2
outputKind = TypeScriptOutputKind.module
outputFileType = TypeScriptFileType.implementationFile
classPatterns = listOf("my.package.here.**")
excludeClassPatterns = listOf("**Companion")
outputFile = "[outputlocation]"
mapEnum = EnumMapping.asEnum
sortTypeDeclarations = true
}
}
My Typescript output looks like this:
export const enum ContentItemType {
THING = 0
}
export interface ThingDataContentDto extends DataContentItem {
type: '0'; # <- I was expecting this to be an ENUM and not a union
title: string;
}
I was expecting the ThingDataContentDto
would use the ContentItemType.THING
enum.
How can I achieve this / what am I doing wrong with the configuration?
garbit commented
Any updates on this?
My only solution so far is to perform a regex on the resulting ts file:
doLast {
val file = File(project.projectDir, "kotlin-dtos.ts")
if (!file.exists()) {
throw RuntimeException("File not found: ${file.absolutePath}")
}
var content = file.readText()
// Enum mapping from TypeScript number to enum
val mapping = mapOf(
"0" to "ContentItemType.THING",
)
// Regex patterns to find and replace types
val patterns = listOf(
Regex("""(?<=interface DataContentItem \{\s+type: )("[0-9]+"(?:\s*\|\s*"[0-9]+")*;)"""),
)
patterns.forEach { regex ->
content = content.replace(regex) { matchResult ->
matchResult.value
.removeSurrounding("\"", ";")
.split(" | ")
.joinToString(" | ") { num -> mapping[num.trim('"')] ?: "ContentItemType.UNKNOWN" } + ";"
}
}
file.writeText(content)
println("Updated TypeScript definitions in ${file.absolutePath}")
}