let's talk more about the validation on the constructor aspect. First your use case sounds like the typical inline class example where you don't want to pay for the overhead of a wrapper type.
So this would be the approach to do that:
@JvmInline
value class Email(val value: String) {
init {
require(value.contains('@')) {"email value $value doesn't contain '@'"}
}
}
At runtime the compiler will have gotten rid of the Email class in most cases, so you have the performance of only handling a String but the type safety of a wrapper type approach.
But as mentioned before the wrapping of your type around a string isn't invisible, so it's either
Email("<mailto:gabrie@test.co|gabrie@test.co>")
or you write an extension function (this time without the validation, since that's taken care of in the init-block).
fun String.toEmail(): Email = Email(this)
For more info on inline classes see
https://kotlinlang.org/docs/inline-classes.html