Swift Academy · Lesson

KeyPath Basics

Reference properties as first-class values.

Lesson 1 of 413 steps

KeyPath Basics is a free Swift Academy lesson on CoddyKit. This is lesson 1 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, and your progress syncs across the web and the CoddyKit app. The Swift Academy course includes 4 lessons in total.

What Is a Key Path?

A key path is a value that describes a path to a property without actually accessing it. Think of it as a stored, reusable reference to which property you want, separate from which instance you read it from.

You write a key path with a backslash, the type name, a dot, and the property name. Swift gives this expression a KeyPath value that you can pass around like any other value.

struct Person {
    let name: String
    let age: Int
}

let nameKeyPath = \Person.name
print(type(of: nameKeyPath))

Reading a Value

To read a property through a key path, use the [keyPath:] subscript on an instance. You pass the key path inside the brackets and Swift returns the value at that path.

This is the runtime counterpart to writing the property name directly, but now the property is chosen by data rather than hard-coded.

struct Person {
    let name: String
    let age: Int
}

let alice = Person(name: "Alice", age: 30)
let path = \Person.name
print(alice[keyPath: path])

Key Path Syntax in Detail

The general form is the backslash escape, then the root type, then a dot, then the property name. The backslash signals to Swift that you want a key path rather than the property's value.

The root type is the type the path starts from. The result type is the type of the final property. So a path from Person to its age property has root Person and value Int.

struct Person {
    let name: String
    let age: Int
}

let ageKeyPath: KeyPath<Person, Int> = \Person.age
let bob = Person(name: "Bob", age: 42)
print(bob[keyPath: ageKeyPath])

Chaining Through Nested Properties

Key paths can drill into nested values. If a property is itself a struct, you can continue the path with another dot to reach a deeper property.

The whole chain is still a single key path value, and its root and result types reflect the start and end of the chain.

struct Address {
    let city: String
}
struct Person {
    let name: String
    let address: Address
}

let cityPath = \Person.address.city
let carol = Person(name: "Carol", address: Address(city: "Oslo"))
print(carol[keyPath: cityPath])

Storing Key Paths in Variables

Because a key path is just a value, you can store it in a variable, return it from a function, or keep a collection of key paths. This lets you decide which property to read at runtime.

Here we pick one of two stored key paths based on a flag.

struct Person {
    let name: String
    let age: Int
}

let showAge = true
let chosen: PartialKeyPath<Person> = showAge ? \Person.age : \Person.name
let dave = Person(name: "Dave", age: 27)
print(dave[keyPath: chosen])

PartialKeyPath and AnyKeyPath

Swift has a small family of key path types. KeyPath<Root, Value> knows both ends. PartialKeyPath<Root> knows the root but erases the value type. AnyKeyPath erases both.

The more type information you keep, the more the compiler can check for you. Reach for the partial or any forms only when you genuinely need to mix paths of different value types.

struct Person {
    let name: String
    let age: Int
}

let paths: [PartialKeyPath<Person>] = [\.name, \.age]
let eve = Person(name: "Eve", age: 19)
for p in paths {
    print(eve[keyPath: p])
}

Shorthand Inside a Known Type

When the root type is already known from context, you can drop the type name and write just the backslash, a dot, and the property. The compiler infers the root.

This shorthand keeps call sites short, especially inside collection operations where the element type is obvious.

struct Person {
    let name: String
    let age: Int
}

func value(of person: Person, at path: KeyPath<Person, Int>) -> Int {
    person[keyPath: path]
}

let frank = Person(name: "Frank", age: 55)
print(value(of: frank, at: \.age))

Key Paths as Function Arguments

A common pattern is a generic function that accepts a key path and applies it to many instances. This decouples what you read from the logic that does the reading.

Here a generic helper extracts any property of any type from a list of people.

struct Person {
    let name: String
    let age: Int
}

func extract<T>(_ people: [Person], _ path: KeyPath<Person, T>) -> [T] {
    people.map { $0[keyPath: path] }
}

let people = [Person(name: "Ana", age: 21), Person(name: "Ben", age: 34)]
print(extract(people, \.name))
print(extract(people, \.age))

Key Paths and Computed Properties

Read-only key paths work with computed properties too. The path captures the computation, so reading through it runs the getter.

This means a key path is not limited to stored properties; any readable property qualifies.

struct Rectangle {
    let width: Double
    let height: Double
    var area: Double { width * height }
}

let areaPath = \Rectangle.area
let r = Rectangle(width: 3, height: 4)
print(r[keyPath: areaPath])

Identity Key Path

There is a special key path that refers to the whole value itself, written as a lone backslash followed by a dot and self. Reading through it returns the instance unchanged.

It is handy when an API expects a key path but you want the element as-is, such as sorting numbers by themselves.

let numbers = [3, 1, 2]
let identity = \Int.self
for n in numbers {
    print(n[keyPath: identity])
}

Comparing Key Paths

Key paths are Hashable and Equatable. Two key paths that point to the same property of the same type are equal, so you can store them in sets or use them as dictionary keys.

This is useful for building tables that map a property to a label or formatter.

struct Person {
    let name: String
    let age: Int
}

let labels: [PartialKeyPath<Person>: String] = [
    \Person.name: "Full Name",
    \Person.age: "Years Old"
]
print(labels[\Person.age] ?? "unknown")

Quick Check: Reading via Key Path

Test your understanding of how to read a property through a key path.

Recap: Key Path Basics

You learned the foundations of key paths:

  • A key path is written with a backslash, the root type, a dot, and a property name, and it describes a property without reading it.
  • Read a value using the [keyPath:] subscript on an instance.
  • Paths can chain into nested properties and target computed properties.
  • KeyPath, PartialKeyPath, and AnyKeyPath trade type safety for flexibility.
  • Key paths are values: store them, pass them, compare them, and use them as dictionary keys.

Next you will use key paths to make collection operations far more concise.

struct Person {
    let name: String
    let age: Int
}

let path = \Person.age
let gina = Person(name: "Gina", age: 48)
print("Read via key path: \(gina[keyPath: path])")
Free to start

Learn Swift with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
122
Lessons
409

Frequently Asked Questions

Is the “KeyPath Basics” lesson free?

Yes — any 3 lessons of the Swift Academy learning path, including “KeyPath Basics”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Swift Academy course includes 4 lessons in total.

What will I learn in “KeyPath Basics”?

Reference properties as first-class values. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Swift Academy?

No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 4.

How long does the “KeyPath Basics” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Swift Academy lesson?

Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. KeyPath Basics
  2. Using KeyPaths in Collections
  3. Writable and Reference KeyPaths
  4. @dynamicMemberLookup
← Back to Swift Academy