0

Why doesn't a Dictionary of type [String: Encodable]() able to cast to Encodable?

let dictionary = [String: Encodable]()
let test = dictionary is Encodable //Returns false

But a dictionary of [String: String]() does work

let dictionaryTwo = [String: String]()
let test = dictionaryTwo is Encodable //Returns true
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
visandres
  • 47
  • 6

2 Answers2

4

The conditional conformance of Dictionary to Encodable looks as follows:

extension Dictionary: Encodable where Key: Encodable, Value: Encodable {
   // ...
}

In English, this means that a Dictionary is Encodable when its Key and Value types are each types which themselves conform to Encodable.

However, [String: Encodable] (also spelled [String: any Encodable]) is not such a type, because any Encodable is not itself a type which can conform to Encodable — it's a way to spell a constraint on a type, rather than a type itself.

For more information, see other questions like Protocol doesn't conform to itself?

Itai Ferber
  • 28,308
  • 5
  • 77
  • 83
-1

Encodable is a protocol, and protocols do not conform to themselves. That is the first issue. To look at it at a more tangible level, the issue is that just because a group of objects are Encodable doesn't mean they can be encoded in the same way.

[String:String] gives enough information so that, because the key and the value are Encodable, the the dictionary is. Here is an example that shows why [String:Encodable]() can't conform.

Suppose I have Foo and Bar:

struct Foo: Encodable {
    let myString: String
    let myInt: Int
}

struct Bar: Encodable {
    let yourString: String
    let yourInt: Int
}

Now I have my dictionary:

var dictionary: [String: Encodable] = [:]
dictionary["fooExample"] = Foo(myString: "whatever", myInt: 100)
dictionary["barExample"] = Bar(yourString: "something", yourInt: 20)

We have a dictionary with keys and values that are all Encodable. If you take a look, though, dictionary["fooExample"] and dictionary["barExample"] encode completely differently. So even though values can individually encode, it doesn't mean that the dictionary with those values can encode.

Ben A.
  • 874
  • 7
  • 23
  • 1
    I didn't downvote your answer, but did want to say: while you're right to point out that several different values in a collection of `any Encodable` could encode differently, this isn't much of an issue. For example, it's perfectly valid to have an array of the _same_ type where several values encode very differently from one another. _However_, this is more of a problem when you go to _decode_, because you cannot attempt to decode a collection of `any Decodable`, because the _static_ type information is necessary in order to know which `init(from:)` needs to be called – Itai Ferber Aug 17 '23 at 19:46
  • That's a fair point to make. – Ben A. Aug 17 '23 at 19:55