DEV Community

Cover image for Types of KeyPath in Swift.
Sergey Leschev
Sergey Leschev

Posted on • Edited on

Types of KeyPath in Swift.

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
  2. ParialKeyPath
  3. AnyKeyPath

And two writable key paths.

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.

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

let firstInteger = \Array<Int>.first
// KeyPath<[Int], Int?>
Enter fullscreen mode Exit fullscreen mode

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.

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

let streetAddress = \User.address?.street
// KeyPath<User, String?>
Enter fullscreen mode Exit fullscreen mode

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

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

let firstInteger = \Array<Int>.first
// KeyPath<[Int], Int?>
Enter fullscreen mode Exit fullscreen mode

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

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

let firstIndexInteger = \[Int][0]
// WritableKeyPath<[Int], Int>
Enter fullscreen mode Exit fullscreen mode

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

struct User {
    var name: String
}

\User.name
// WritableKeyPath<User, String>
Enter fullscreen mode Exit fullscreen mode

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

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>
Enter fullscreen mode Exit fullscreen mode

Next Article: KeyPath Usage in Swift

Previous Article: KeyPath in Swift


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

Top comments (0)