Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.adamko.kxstsgen

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.InheritableSerialInfo

/**
* Marks a property as required in the generated TypeScript interface.
*
* This annotation is inheritable, so it should be sufficient to place it on a base class of hierarchy.
*
* This annotation should only be used if [kotlinx.serialization.json.JsonConfiguration.encodeDefaults]
* is set to true. If it is false (which it is by default), then properties with default values are
* potentially omitted from the generated JSON.
*/
@InheritableSerialInfo
@Target(AnnotationTarget.PROPERTY)
@ExperimentalSerializationApi
annotation class KxsTsRequired
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.adamko.kxstsgen.core

import dev.adamko.kxstsgen.KxsTsRequired
import kotlinx.serialization.descriptors.PolymorphicKind
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
Expand Down Expand Up @@ -207,7 +208,9 @@ fun interface TsElementConverter {
return descriptor.elementDescriptors.mapIndexed { index, fieldDescriptor ->
val name = descriptor.getElementName(index)
val fieldTypeRef = typeRefConverter(fieldDescriptor)
val optional = descriptor.isElementOptional(index)
val optional =
descriptor.getElementAnnotations(index).none { it is KxsTsRequired }
&& descriptor.isElementOptional(index)
TsProperty(name, fieldTypeRef, optional)
}.toSet()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dev.adamko.kxstsgen.core

import dev.adamko.kxstsgen.KxsTsConfig
import dev.adamko.kxstsgen.KxsTsGenerator
import dev.adamko.kxstsgen.KxsTsRequired
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import kotlinx.serialization.Serializable

class KxsTsGeneratorTest : FunSpec({
val config = KxsTsConfig(indent = " ")
val tsGenerator = KxsTsGenerator(config)

test("Can make default-valued properties required") {
@Serializable
data class OptionalTest(
val optional: Boolean = false,
@KxsTsRequired
val required: Boolean = true,
)

tsGenerator.generate(OptionalTest.serializer()) shouldBe """
|export interface OptionalTest {
| optional?: boolean;
| required: boolean;
|}
""".trimMargin()
}

test("Can make nullable properties required") {
@Serializable
data class OptionalTest(
@KxsTsRequired
val required: Boolean? = null,
val optional: Boolean? = null,
)

tsGenerator.generate(OptionalTest.serializer()) shouldBe """
|export interface OptionalTest {
| required: boolean | null;
| optional?: boolean | null;
|}
""".trimMargin()
}
})