I think you're mixing up two different issues. One is whether the compiler is supposed to synthesize Codable conformance from your Customer class. The other is the correct type for a dictionary of "arbitrary" structure. (Note that because it's coming from JSON, it's not completely arbitrary. All the keys must actually be strings, and all valid JSON values are Codable-conforming.)
So, I tried writing out manually the code that the compiler is supposed to synthesize, which looks like this:
struct Customer: Codable {
let id: String
let email: String
let metadata: [String: Any]
enum CustomerKeys: String, CodingKey
{
case id, email, metadata
}
init (from decoder: Decoder) throws {
let container = try decoder.container (keyedBy: CustomerKeys.self)
id = try container.decode (String.self, forKey: .id)
email = try container.decode (String.self, forKey: .email)
metadata = try container.decode ([String: Any].self, forKey: .metadata)
}
func encode (to encoder: Encoder) throws
{
var container = encoder.container (keyedBy: CustomerKeys.self)
try container.encode (id, forKey: .id)
try container.encode (email, forKey: .email)
try container.encode (metadata, forKey: .metadata)
}
}
That compiles just fine. So the problem is not the dictionary type. (Presumably, if you tried to encode a [String: Any] that contained values of unencodable types, you'd get an exception. Presumably, decoding valid JSON would never fail, since all the value types would be decodable and assignable to Any.)
The problem is that the compiler won't synthesize the above code because of the presence of "Any" as the dictionary value type. This is either a simple bug, an area of Codable support that hasn't been implemented yet, or a more subtle issue. Either way, the correct place to ask about it is over on the swift-users mailing list.