KeyPaths 101
We will start with a very, very simple example. Below, we create a User type that has just one property, the username. Then, we initialize the user as firstUser and want to print out firstUsers username.
Normally, we would do print(firstUser.username) but instead we're doing something else. Have a look:
struct User {
var username: String
}
let firstUser = User(username: \"Player 1\")
print(firstUser[keyPath: \User.username])
You'll easily see the difference. Instead of using firstUser.username we're using a very weird syntax:
firstUser[keyPath: \User.username]
This tells Swift that we want to access the contents of the property username of the type User on the instance firstUser.
It is comparable to dictionary access (dict["Hello"]), only that you don't use String keys ("Hello") but something type-safe. Namely, a Swift keypath.
At first glance, this looks like an overly verbose version of direct access, so what else can it do? For one, we can abstract the access away. We can store the KeyPath in a variable:
let userKeyPath = \User.username
print(firstUser[keyPath: userKeyPath])
By doing so, we implement generic abstraction between the property and the type. But, what is the type of this userKeyPath variable? The full type signature looks like this:
let keyPath: KeyPath<User, String> = \User.username
KeyPath has two generic types:
- The
Root. It is thestruct,class, orenumwhose property you want to have aKeyPathto. APerson, aUIViewController, aString, or something else - This is the
Value. It is a property on theRoottype. For example aPerson'sname, or aUIViewController'stitle, or aString'scount.
So in our example, the Root is User, and the Value is String because username is of type String. Here is an overview.

