Reading — step 1 of 4
Learn
~1 min readProperty Wrappers and Key Paths
A key path is a typed reference to a property — like a pointer to a setter/getter, but compile-time-checked.
struct Person {
var name: String
var age: Int
}
let keyPath = \Person.name // KeyPath<Person, String>
let ada = Person(name: "Ada", age: 36)
ada[keyPath: keyPath] // "Ada"
The \Type.property syntax creates a key path. Apply it to an instance with instance[keyPath: kp].
Higher-order use:
let people = [
Person(name: "Ada", age: 36),
Person(name: "Bob", age: 25),
]
// Sort by age:
let sorted = people.sorted { $0.age < $1.age }
// Or with key path:
let sortedByAge = people.sorted(using: KeyPathComparator(\.age))
// Map to a property:
let names = people.map(\.name) // ["Ada", "Bob"]
map(\.name) is shorthand for map { $0.name }. Compile-time-checked, slightly more concise.
WritableKeyPath — for mutable properties:
let writeKp: WritableKeyPath<Person, String> = \Person.name
var p = Person(name: "Ada", age: 36)
p[keyPath: writeKp] = "Linus"
ReferenceWritableKeyPath — for class properties (since classes have reference semantics).
Use cases:
- Generic functions over arbitrary properties
- Reactive frameworks (Combine, SwiftUI) heavily use key paths to wire bindings
- Dependency injection containers
- Diff calculation in CoreData / SwiftData
Key paths are how \.property syntax works in @Binding(get:set:), sort/filter operations, and Combine's assign(to:on:).
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…