swiftswift-keypath

how do you write a KeyPath to reference the value of a dictionary


Say I have a struct like this:

struct Person {
  var kids: [KidId: KidName] = [:]
}

Is it possible to construct a keypath to reference the value of something in the User.kids property? Something like \User.kids[KidId]?

Specifically, I'd like to construct a WritableKeyPath<User,KidName>. I thought you could keypath into both dictionaries and arrays, but I can't for the life of me find the syntax anywhere on the internet. Maybe it's not possible?


Solution

  • Your question is unclear because you refer to User in your text, but have Person in your code. That suggests that you might have the syntax right but a hierarchy wrong.

    You also may just be forgetting the question mark.

    To get the type you're asking about, you also need a KidID (the D is capitalized in Swift) value, not the KidID type.

    typealias KidID = String
    enum KidName { case goatBoy }
    \Person.kids["🐐"] as WritableKeyPath<Person, KidName?>
    Person(kids: ["🐐": .goatBoy])[keyPath: \.kids["🐐"]] // .goatBoy
    

    You don't have to supply a value in the key path, but that is a different type.

    \Person.kids as WritableKeyPath<Person, [KidID: KidName]>
    Person(kids: ["🐐": .goatBoy])[keyPath: \.kids]["🐐"] // .goatBoy