Accessing property wrapper itself using keypaths

Is it possible to somehow access property wrapper by using keypaths? I'm referring to the using underscore to get to the wrapper instead of the wrapped value.

Let's say I've got following property wrapper:

@propertyWrapper
public class Wrapper<Value> {
     let key: String
     private let defaultValue: Value

     public init(
          key: String, default: Value
    ) {
          self.key = key
          self.defaultValue = `default`
    }

     var wrappedValue: Value { ... }
}

and class that uses it:

final class Test {
    @Wrapper(key: "key", defaultValue: false)
    var enabled: Bool
}

I'd like to create extension that would let me access both wrapped value and key of the wrapper. Something like:

extension Test {
    func snapshot(for keyPath: KeyPath<Test, Bool>) -> (String, Bool) {
        let value = self[keyPath: keyPath]
        let key = ?? // somehow access keypath of _enabled instead of enabled
        return (key, value)
    }
}

I'm not sure if that's even possible but any feedback would be helpful.

1 Like

If your property wrapper provided a computed property

public var projectedValue: Self { self }

and its key was public, you could do this by changing func snapshot to use the wrapper instead. Can do it generically even:

extension Test {
    func snapshot<T>(for keyPath: KeyPath<Test, Wrapper<T>>) -> (String, T) {
        let wrapper = self[keyPath: keyPath]
        return (wrapper.key, wrapper.wrappedValue)
    }
}

let test: Test
test.snapshot(for: \.$enabled)

Or, if this was the only special use case for a wrapped property, you could make the projected value itself be that key-value pair, with no way to access the property wrapper other than _enabled.