Using Type Aliases
Aliases do not change what a program does — they change how it reads. The two payoffs are shorter signatures and clearer intent.
Documenting Intent
An alias gives a primitive a meaningful name at the point of use. UserId says more than uint64, even though the two are interchangeable:
type UserId = uint64;
func Find(id: UserId) -> *User {
// Code here
}
let admin: UserId = 1;
Find(admin); // OK — UserId is uint64Because an alias is transparent, no cast is needed to pass a uint64 where a UserId is expected, or vice versa.
Shortening Complex Signatures
The benefit grows with the size of the type. A nested array or a function type repeated across several declarations is easier to read — and to change — behind one name:
type Matrix4 = float32[4][4];
func Identity() -> Matrix4 { /* … */ }
func Multiply(a: Matrix4, b: Matrix4) -> Matrix4 { /* … */ }Updating the underlying type in one type declaration updates every use at once.
Aliases Are Not New Types
An alias never introduces a separate type, so it offers no protection against mixing values that happen to share a representation:
type UserId = uint64;
type OrderId = uint64;
let user: UserId = 1;
let order: OrderId = user; // OK — both are just uint64; the compiler sees no differenceIf you want the compiler to treat two ids as incompatible, wrap the value in a single-field struct, which is a distinct type. Reach for an alias when readability is the goal and for a struct when type separation is.
See Also
- Type Aliases — the alias overview and transparency
- Function Type Aliases — naming callback signatures
- Structures — when you need a genuinely distinct type