Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

I like this direction, but you can't constrain typealiases in this way:

protocol P1 { associatedtype Unevaluated }
protocol P2 { associatedtype Unevaluated }
typealias P3 = P1 & P2 where P1.Unevaluated == P2.Unevaluated
// => error: 'where' clause cannot be attached to a non-generic declaration
//    typealias P3 = P1 & P2 where P1.Unevaluated == P2.Unevaluated
//                           ^

You would also need specific instantiations of P1 and P2 (Encodable and Decodable) whose associated types are given concrete values.

This is possible:

struct _Unevaluated {}

protocol P1 {
    typealias Unevaluated = _Unevaluated
}

protocol P2 {
    typealias Unevaluated = _Unevaluated
}

typealias P3 = P1 & P2
print(P3.Unevaluated.self) // => _Unevaluated

but works in a surprising way. P3 actually shows two different overloads for Unevaluated; they just happen to both be the same. You can actually do this:

struct _Unevaluated1 {}
struct _Unevaluated2 {}

protocol P1 {
    typealias Unevaluated = _Unevaluated1
}

protocol P2 {
    typealias Unevaluated = _Unevaluated2
}

typealias P3 = P1 & P2
print(P3.Unevaluated.self) // => _Unevaluated2

I'm not sure how Swift chooses which one "wins", but this appears to return _Unevaluated2 regardless of whether you write P1 & P2 or P2 & P1 (it's possible the composition is always sorted and the last definition wins out; I'm just surprised there are no warnings or anything). That's neither here nor there though.

Seems like we can expand the protocols to contain this (and can potentially include a matching _'d type as the actual underlying type for the protocols). @jrose How does adding typealiases to protocols interact with the ABI?