The typealias can be handy to define very simple types. But be aware that it is not represented in bytecode — typealiases are simply replaced by the type they represent during compilation, and so can’t be used to distinguish between different aliased types in function signatures.
This also has consequences for dependency injection. When bean injection relies on naming and that bean gets renamed, Spring may silently inject an alternative based on type matching, leading to unexpected behaviour.
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
typealias TypeOne = String
typealias TypeTwo = String
typealias SignatureOne = () -> String
typealias SignatureTwo = () -> String
@SpringBootTest
class ExperimentMilo {
@TestConfiguration
class TestConfig {
@Bean
fun funOne(): SignatureOne = { "FunOne" }
@Bean
fun funTwo(): SignatureTwo = { "FunTwo" }
}
@Autowired lateinit var funOne: SignatureOne
@Autowired lateinit var funTwo: SignatureTwo
@Autowired @Qualifier("funOne") lateinit var functionOne: SignatureOne
@Autowired @Qualifier("funTwo") lateinit var functionTwo: SignatureTwo
@Test
fun testBeanSignature() {
val resultOne = funOne.invoke()
val resultTwo = funTwo.invoke()
Assertions.assertEquals("FunOne", resultOne)
Assertions.assertEquals("FunTwo", resultTwo)
}
@Test
fun testBeanSignature2() {
val resultOne = functionOne.invoke()
val resultTwo = functionTwo.invoke()
Assertions.assertEquals("FunOne", resultOne)
Assertions.assertEquals("FunTwo", resultTwo)
}
@Test
fun testFunctionSignature() {
val one: TypeOne = "One"
val two: TypeTwo = "Two"
val resultOneTwo = testSignature(one, two)
val resultTwoOne = testSignature(two, one)
Assertions.assertEquals(Pair("One", "Two"), resultOneTwo)
Assertions.assertEquals(Pair("Two", "One"), resultTwoOne)
}
fun testSignature(one: TypeOne, two: TypeTwo): Pair<TypeOne, TypeTwo> {
return Pair(one, two)
}
}
More information in the official Kotlin documentation on type aliases.
Leave a Reply