Creating a property wrapper with an inherited wrappedValue property

74 Views Asked by At

TL;DR

Is it possible for a @propertyWrapper to have an inherited wrappedValue property when it conforms to a protocol that already defines it?

If we do not explicitly specify the wrappedValue property, then we get the error:

Property wrapper type does not contain a non-static property named 'wrappedValue'

Example

Suppose we have a model like:

struct User: Decodable {
    @DefaultFalse var isVerified: Bool
    ...
}

where @DefaultFalse is a @propertyWrapper that defaults the property to false if it is decoded as null.

To achieve this we could design a generalized protocol like:

protocol Default: Decodable {
    associatedtype Value: Decodable

    static var defaultValue: Value { get }
    var value: Value? { get set }
}

extension Default {

    var wrappedValue: Value {
        get { value ?? Self.defaultValue }
        set { value = newValue }
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if container.decodeNil() {
            value = nil
        } else {
            value = try container.decode(Value.self)
        }
    }
}

Where @Default is a protocol that could default any Decodable value (not just Bool). Our @DefaultFalse implementation might look like:

@propertyWrapper struct DefaultFalse: Default {
    static let defaultValue = false
    var value: Bool?
}

but this errors with the above.

I understand in this example it would be simpler to just use Bool? and fallback with isVerified ?? false - but I've attempted to simplify a use case.

Other

I found a similar question on Swift Forums without an answer at this time.

0

There are 0 best solutions below