I'm trying to add a JSONType
protocol with no requirements that can be implemented by any type that can be passed to JSONSerialization.data(withJSONObject:)
so that I know at compile time that the passed argument is a valid JSON object.
I'm facing the following problem with this code:
public protocol JSONType {
}
extension String: JSONType {
}
extension Array: JSONType where Element: JSONType {
}
func serializeToJSON(_ object: JSONType) -> Data {
return try! JSONSerialization.data(withJSONObject: object)
}
var array1: [JSONType] = [""]
var array2: [JSONType] = [""]
array1[0] = array2 // compile error: Value of type '[JSONType]' does not conform to 'JSONType' in subscript assignment
To me it seems that the Array
extension does just what the compiler is complaining to be missing. Is there a workaround or a more correct solution?
EDIT 1: when setting extension Array: JSONType where Element == JSONType
as suggested in this comment, the code above compiles, but then the following doesn't:
public protocol JSONType {
}
extension String: JSONType {
}
extension Array: JSONType where Element == JSONType {
}
extension Dictionary: JSONType where Key == String, Value == JSONType {
}
var dict = [String: JSONType]()
dict[""] = [[String: JSONType]]() // compile error: Generic struct 'Array' requires the types '[String : JSONType]' and 'JSONType' be equivalent
... which then compiles again when resetting to extension Array: JSONType where Element: JSONType
.
EDIT 2: I tried using JSONEncoder
, but this gives similar compiler errors:
func serializeToJSON<T>(_ object: T) -> Data where T: Encodable {
return try! JSONEncoder().encode(object)
}
var dict = [String: Encodable]()
dict[""] = [[String: Encodable]]() // compile error: Cannot assign value of type '[[String : Encodable]]' to subscript of type 'Encodable?'
var array1: [Encodable] = [""]
var array2: [Encodable] = [""]
array1[0] = array2 // compile error: Value of type '[Encodable]' does not conform to 'Encodable' in subscript assignment
serializeToJSON(dict) // compile error: Protocol 'Encodable' as a type cannot conform to the protocol itself
serializeToJSON(array1) // compile error: Protocol 'Encodable' as a type cannot conform to the protocol itself
When using Any
instead of Encodable
the compiler says Protocol 'Any' as a type cannot conform to 'Encodable'
.