Types of KeyPath in Swift.
Tags: swift, mobile, ios, programming
Published: 2023-01-29 07:37:09

Swift has five key path types, but we can categorize them into **two groups** based on their functions.

1. **Read-only** key paths.
2. **Writable** key paths (Can read and write).

We have **three** read-only key paths.

1. [KeyPath](https://developer.apple.com/documentation/swift/keypath)
2. [ParialKeyPath](https://developer.apple.com/documentation/swift/partialkeypath)
3. [AnyKeyPath](https://developer.apple.com/documentation/swift/anykeypath)

And **two** writable key paths.

- [WritableKeyPath](https://developer.apple.com/documentation/swift/writablekeypath)
- [ReferenceWritableKeyPath](https://developer.apple.com/documentation/swift/referencewritablekeypath)

I will only focus on three basic types of key paths in this article.

1 `KeyPath`: A read-only access to a property. Root type can be both value/reference semantics.
2 `WritableKeyPath`: Provides read-write access to a mutable property with **value semantics** (such as `struct` and `enum`).
3 `ReferenceWritableKeyPath`: Provides reading and writing to a mutable property with **reference semantics** (such as `class`).

## How can key path type inferred
In the last section, when we construct key paths, you can see that we only get `KeyPath` and `WritableKeyPath`.

```swift
let firstIndexInteger = \[Int][0]
// WritableKeyPath<[Int], Int>

let firstInteger = \Array<Int>.first
// KeyPath<[Int], Int?>
```

**Key path infers from the properties/subscripts and a root type.**

- If properties or subscripts are read-only (such as `let` or `subscript` with only `get`), `KeyPath` is inferred.

- If it is mutable (such as `var` or `subscript` with `get/set`).
-- With a root of value types (such as `struct` and `enum`), `WritableKeyPath` is inferred.
-- With a root of reference types (such as `class`), `ReferenceWritableKeyPath` is inferred.

We declare every property with `let`, so we get `KeyPath` as a result.

```swift
let userRole = \User.role
// KeyPath<User, Role>

let streetAddress = \User.address?.street
// KeyPath<User, String?>
```

`first` and `debugDescription` are read-only computed properties, so we also get `KeyPath` as a result.

```swift
let stringDebugDescription = \String.debugDescription
// KeyPath<String, String>

let firstInteger = \Array<Int>.first
// KeyPath<[Int], Int?>
```

We get `WritableKeyPath` when reference array `subscript` because it is a read-write subscript (`get/set`).

```swift
subscript(index: Int) -> Element { get set }

let firstIndexInteger = \[Int][0]
// WritableKeyPath<[Int], Int>
```

If we change the `name` property to `var`, we will get `WritableKeyPath` when reference `\User.name`.

```swift
struct User {
    var name: String
}

\User.name
// WritableKeyPath<User, String>
```

If we change `User` to `class`, key path to `var` and `let` will be `ReferenceWritableKeyPath` and `KeyPath`, respectively.

```swift
class User {
    var name: String
    let email: String
    
    init(name: String, email: String) {
        self.name = name
        self.email = email
    }
}

\User.name
// ReferenceWritableKeyPath<User5, String>

\User.email
// KeyPath<User, String>
```

---

Next Article: [KeyPath Usage in Swift](https://dev.to/sergeyleschev/keypath-usage-in-swift-393p)

Previous Article: [KeyPath in Swift](https://dev.to/sergeyleschev/keypath-in-swift-1mpg)

---

**Contacts**
I have a clear focus on time-to-market and don't prioritize technical debt. And I took part in the Pre-Sale/RFX activity as a System Architect, assessment efforts for Mobile (iOS-Swift, Android-Kotlin), Frontend (React-TypeScript) and Backend (NodeJS-.NET-PHP-Kafka-SQL-NoSQL). And I also formed the work of Pre-Sale as a CTO from Opportunity to Proposal via knowledge transfer to Successful Delivery.

🛩️ #startups #management #cto #swift #typescript #database
📧 Email: sergey.leschev@gmail.com
👋 LinkedIn: https://linkedin.com/in/sergeyleschev/
👋 LeetCode: https://leetcode.com/sergeyleschev/
👋 Twitter: https://twitter.com/sergeyleschev
👋 Github: https://github.com/sergeyleschev
🌎 Website: https://sergeyleschev.github.io
🌎 Reddit: https://reddit.com/user/sergeyleschev
🌎 Quora: https://quora.com/sergey-leschev
🌎 Medium: https://medium.com/@sergeyleschev
🖨️ PDF Design Patterns: [Download](https://sergeyleschev.github.io/sergeyleschev-design-patterns.pdf)