Rust: Type Aliases

Home · Blog

19 March 2023

A type alias defines a new name for a type using the type keyword. For example, let’s say we have a type for a 3-element vector. If we use those 3 elements for red, green, and blue, we can use the same data structure for colors:

struct Vec3(f64, f64, f64);
type Color = Vec3;

Now we can use Color and Vec3 pretty much interchangeably: we can assign a Color to a variable of type Vec3 and vice versa, define a method on one type and call it on the other, define a function that takes one type and call it with the other, and so on. The one thing we can’t do is use Color as a constructor. For that we still need Vec3:

let c: Color = Vec3(0.5, 0.5, 1.0);

Type aliases are mostly used to avoid repetition with complex types. For example, some packages define their own Error type, and then also define a Result type like this:

type Result<T> = std::result::Result<T, Error>;

Use alias

The use keyword offers another way to define an alias:

struct Vec3(f64, f64, f64);
use Color = Vec3;

Here we can really use Color in any place where we’d have used Vec3 before, including as a constructor:

let c = Color(0.5, 0.5, 1.0);

I don’t think this is common in Rust though -- that’s not what the use keyword is meant for. I’m just mentioning it here for completeness.

The newtype pattern

The limitation of type aliases is that they don’t provide any extra type safety. Defining Color as an alias for Vec3 won’t stop you from accidentally calling a function expecting a Color with a Vec3 that represents a point in 3D space. If that’s what you’re looking for, you need the newtype pattern. (The name comes from Haskell, I think, which has a newtype keyword that does the same thing.)

The idea is to define a new type as a tuple struct with a single element, so it’s basically a wrapper for another type:

struct Meters(f64);
struct Feet(f64);

Now if you try to assign a value of type Meters to a variable of type Feet, the compiler will stop you. The downside is that all the operators and methods of f64 won’t work on Meters and Feet, so you may have to write a lot of repetitive code to do things like add two values of type Meter.