In Rust, you can use the type keyword to create an alias for an existing type. For example:
type Kilometers = i32; fn add_distance(x: Kilometers, y: Kilometers) -> Kilometers { x + y }
Kilometers is just another name for i32; the compiler does not differentiate between these types, and they are completely interchangeable.
Newtype pattern is creating a new wrapper structure for an existing type:
struct Kilometers(i32); // a separate new type fn add_distance(x: Kilometers, y: Kilometers) -> Kilometers { Kilometers(x.0 + y.0) }
Now Kilometers and i32 are different types, and they cannot be confused.
The choice between these approaches depends on safety and readability requirements. For public APIs and especially type-safe units of measurement, use newtype.
What is the difference between
typealias and newtype pattern in Rust? Can you limit operations for a type alias through trait implementation?
It is often answered that an alias can be used for access control and limiting operations, but that's not true — an alias does not create a new type, and thus unique traits cannot be implemented for it. Only the newtype pattern is a separate type, for which unique behavior can be implemented.
type UserId = u64; struct UserIdNew(u64); trait Foo { fn foo(&self); } // Implementing Foo for UserId is not possible because it's just u64. // For UserIdNew — it is possible.
Story
In the project, distances were measured in meters and millimeters using aliases:
type Millimeters = u32; type Meters = u32;In the final code, millimeters were accidentally added to meters, leading to calculation errors. The typing didn't catch this — the compiler didn't catch it at all. Switching to newtype resolved the issue.
Story
In a public API, aliases were used for identifiers of different entities (
type UserId = u64;,type OrderId = u64;). Confusion arose: someone mixed up the parameters, and a bug went into production due to the inability to distinguish them by types.
Story
A developer attempted to implement unique behavior for the Display trait for a type alias:
type MyType = String; impl Display for MyType { ... }The compiler raised an error: "cannot implement trait for type alias". The problem was resolved through the newtype pattern.