While using type
can improve readability in some cases, if you use it to create an alias it won't make your code safer or easier to refactor. Consider:
type A = String
def m(s: A) = s.length
m("12345") // It's "safe" to use String instead of A
If you want a wrapper so you don't pass e.g. user login where user name is expected (both strings), you can use a value class:
class UserName(val name: String) extends AnyVal
def m(name: UserName) = name.name.length
m("12345") //> error: type mismatch
m(new UserName("12345")) //> 5
Value classes have a very small footprint, in fact they operate with their underlying object directly. If you look at the generated code it will in fact be:
def m(name: String): Int = name.length();
m("12345")
type
shines when you need to create type expressions, e.g.:
type ¬[A] = A => Nothing
type ¬¬[A] = ¬[¬[A]]
type ∨[T, U] = ¬[¬[T] with ¬[U]]
type |∨|[T, U] = { type λ[X] = ¬¬[X] <:< (T ∨ U) }
(the first thing which came my mind, credit to Miles Sabin)