Reputation: 431
I need to restrict the caller of the function to only use the string "asc" or "desc", so I want to use a constant to define the type.
When I use typescript, I can do like this:
function test(order: "asc" | "desc") {
// ...
}
Then order can only be either "asc" or "desc". So how to define order
in Scala?
Upvotes: 1
Views: 172
Reputation: 27356
sealed trait order
case object asc extends order
case object desc extends order
Automatic conversion
You can automatically convert String
to order
using an implicit conversion:
object order {
implicit def string2order(s: String): order = s match {
case "asc" => asc
case "desc" => desc
}
}
Once this is defined you can pass a String
to a method that takes order
and it will be automatically converted. (There will be a MatchError
if an invalid value is given).
Note that using strings in this way is not recommended; just use the case objects directly for better type safety.
Note that I have preserved the case of order
, asc
and desc
to match your question, but Scala convention is to use capital letters for class and object names (Order
, Asc
, Desc
)
Upvotes: 3
Reputation: 1016
so sadly we don't quite yet have Union Types like this. they're slotted to be in dotty though not for singleton types as in your example afaik.
The most common way it to employ an sealed trait hierarchy like this
sealed trait Order
final case object Asc extends Order
final case object Desc extends Order
It is important that the trait is final and the case classes/object final so that the compiler can do exhaustiveness checks
val ord:Order = Asc
val ord2:Order = Desc
are the only 2 possible cases because neither the trait nor the case classes/objects can be extended any further. that means that every instance of type Order
has to be either Asc
or Desc
ord match {
case Asc => ???
case Desc => ???
}
to pattern match on an Order
and then do whatever
EDIT: The "anonymous" way to do this would be through the Either[A, B]
datatype though that'd also require the use of singleton types (which you can get through some libraries like shapeless) or you'd just end up with Either[String, String]
which is meh.
Upvotes: 2