Customising Output
Overriding output
If you want to override what KotlinTsGen produces, then you can provide overrides.
By default, Double is transformed to a generated Double alias. We can customise that alias with
the mapTypes DSL.
import kotlinx.serialization.builtins.serializer
import io.github.esafak.kotlintsgen.core.*
@Serializable
data class Item(
val price: Double,
val count: Int,
)
fun main() {
val tsGenerator = KotlinTsGenerator()
tsGenerator.mapTypes {
Double.serializer() mapsTo typeAlias("Double", ref("double"))
}
println(tsGenerator.generate(Item.serializer()))
}
See the type-alias example.
export interface Item {
price: Double;
count: Int;
}
export type Double = double; // assume that 'double' will be provided by another library
export type Int = number;
Referencing external types
If a type is already provided by another TypeScript library, use external to reference it without
emitting a declaration. Nullable Kotlin properties retain their nullability.
import kotlinx.serialization.builtins.serializer
import io.github.esafak.kotlintsgen.core.*
@Serializable
data class Position(
val x: Double,
val y: Double?,
)
fun main() {
val tsGenerator = KotlinTsGenerator()
tsGenerator.mapTypes {
Double.serializer() mapsTo external("double")
}
println(tsGenerator.generate(Position.serializer()))
}
See the external-type example.
export interface Position {
x: double;
y: double | null;
}
Instead of changing the output to be a type alias, a custom 'literal' type can be set instead.
import kotlinx.serialization.builtins.serializer
import io.github.esafak.kotlintsgen.core.*
@Serializable
data class Item(
val price: Double,
val count: Int,
)
fun main() {
val tsGenerator = KotlinTsGenerator()
tsGenerator.descriptorOverrides +=
Double.serializer().descriptor to TsLiteral.Custom("customDouble")
println(tsGenerator.generate(Item.serializer()))
}
See the custom-literal example.
This produces no type alias, and Double is overridden to be customDouble.
export interface Item {
price: customDouble;
count: Int;
}
export type Int = number;
Override nullable properties
Even though UInt is nullable, it should be overridden by the UInt defined in descriptorOverrides.
import kotlinx.serialization.builtins.serializer
import io.github.esafak.kotlintsgen.core.*
@Serializable
data class ItemHolder(
val item: Item,
)
@Serializable
data class Item(
val count: UInt? = 0u,
val score: Int? = 0,
)
fun main() {
val tsGenerator = KotlinTsGenerator()
tsGenerator.descriptorOverrides +=
UInt.serializer().descriptor to TsDeclaration.TsTypeAlias(
id = TsElementId("kotlin.UInt"),
typeRef = TsTypeRef.Declaration(id = TsElementId("uint"), parent = null, nullable = false)
)
tsGenerator.descriptorOverrides += Int.serializer().descriptor to TsLiteral.Custom("customInt")
println(tsGenerator.generate(ItemHolder.serializer()))
}
See the nullable-property override example.
export interface ItemHolder {
item: Item;
}
export interface Item {
count?: UInt | null;
score?: customInt | null;
}
export type UInt = uint;
Override both nullable and non-nullable descriptors
Tick has a non-nullable UInt, while Item has a nullable UInt. Also, in ItemHolder, Tick is
nullable. Even though a non-nullable override for UInt is supplied, the output shouldn't have
conflicting overrides.
import kotlinx.serialization.builtins.serializer
import io.github.esafak.kotlintsgen.core.*
@Serializable
@JvmInline
value class Tick(val value: UInt)
@Serializable
@JvmInline
value class Phase(val value: Int)
@Serializable
data class ItemHolder(
val item: Item,
val tick: Tick?,
val phase: Phase?,
)
@Serializable
data class Item(
val count: UInt? = 0u,
val score: Int? = 0,
)
fun main() {
val tsGenerator = KotlinTsGenerator()
tsGenerator.descriptorOverrides +=
UInt.serializer().descriptor to TsDeclaration.TsTypeAlias(
id = TsElementId("kotlin.UInt"),
typeRef = TsTypeRef.Declaration(id = TsElementId("uint"), parent = null, nullable = false)
)
tsGenerator.descriptorOverrides += Int.serializer().descriptor to TsLiteral.Custom("customInt")
println(tsGenerator.generate(ItemHolder.serializer()))
}
export interface ItemHolder {
item: Item;
tick: Tick | null;
phase: Phase | null;
}
export interface Item {
count?: UInt | null;
score?: customInt | null;
}
export type Tick = UInt;
export type Phase = customInt;
export type UInt = uint;