Avatar
@swift-5.2.5 import Foundation @propertyWrapper struct DefaultValue<Storage: DefaultValueStorage>: Decodable { var wrappedValue: Storage.Value = Storage.value } extension DefaultValue { init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() self.wrappedValue = try container.decode(Storage.Value.self) } } protocol DefaultValueStorage { associatedtype Value: Decodable static var value: Value { get } } enum DefaultValueStorages { enum Nil<T: Decodable>: DefaultValueStorage { static var value: T? { nil } } } // MARK: - 1. 直接書く struct S1 { @DefaultValue<DefaultValueStorages.Nil<String>> var string } // MARK: - 2. 別enumでtypealiasする enum Default { typealias Nil<T: Decodable> = DefaultValue<DefaultValueStorages.Nil<T>> } struct S2 { @Default.Nil<String> var string } // MARK: - 3. extension DefaultValueでtypealiasする extension DefaultValue { typealias Nil<T: Decodable> = DefaultValue<DefaultValueStorages.Nil<T>> } struct S3 { @DefaultValue.Nil<String> var string }