# Another "Value of protocol type cannot conform because only struct/enum/class types can conform to protocols" post

**URL:** <https://forums.swift.org/t/another-value-of-protocol-type-cannot-conform-because-only-struct-enum-class-types-can-conform-to-protocols-post/47548>\
**Category:** Using Swift\
**Tags:** generics, protocols\
**Created:** [April 19, 2021, 7:55pm UTC](https://forums.swift.org/t/another-value-of-protocol-type-cannot-conform-because-only-struct-enum-class-types-can-conform-to-protocols-post/47548 "2021-04-19T19:55:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![NSExceptional](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nsexceptional/32/6813_2.png) [@NSExceptional](https://forums.swift.org/u/NSExceptional)\
**Post date:** [April 19, 2021, 7:55pm UTC](https://forums.swift.org/t/another-value-of-protocol-type-cannot-conform-because-only-struct-enum-class-types-can-conform-to-protocols-post/47548/1 "2021-04-19T19:55:08Z")

</div>

Consider a protocol `JSON` which represents any valid JSON object. We might define it like so:

```swift
protocol JSON { }
extension String: JSON { }
extension Int: JSON { }
... // and so on
extension Array: JSON where Element: JSON { }
extension Dictionary: JSON where Key == String, Value: JSON { }

```

The above implies that a dictionary of type `[String: JSON]` itself should be a `JSON`. Yet, I am unable to use it like below without the following warnings:

```swift
// Case 1: Error: Cannot convert value of type 'Int'
// to expected dictionary value type 'String'
let foo: JSON = ["name": "Bob", "age": 25]

// Case 2: Error: Value of protocol type 'JSON'
// cannot conform to 'JSON'; only struct/enum/class
// types can conform to protocols
func foo(_ json: JSON)

let json: [String: JSON] = ["name": "Bob", "age": 25]
foo(json) // error

```

I have a hunch this has to do with the `some P`/`any P` stuff. Can someone tell me why what I'm trying to do is not yet possible?

Edit: [this post](https://forums.swift.org/t/allowing-self-conformance-for-protocols/39841/6) seems extremely related. I am reading through it.

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [April 19, 2021, 8:20pm UTC](https://forums.swift.org/t/another-value-of-protocol-type-cannot-conform-because-only-struct-enum-class-types-can-conform-to-protocols-post/47548/2 "2021-04-19T20:20:09Z")

</div>

I think you want `Value == JSON { }`. The type of `["name": "Bob", "age": 25]` is _effectively_ `[String: JSON]` but `JSON` doesn't conform to itself.

---

<div class="post-metadata">

**Author:** ![NSExceptional](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nsexceptional/32/6813_2.png) [@NSExceptional](https://forums.swift.org/u/NSExceptional)\
**Post date:** [April 19, 2021, 8:26pm UTC](https://forums.swift.org/t/another-value-of-protocol-type-cannot-conform-because-only-struct-enum-class-types-can-conform-to-protocols-post/47548/3 "2021-04-19T20:26:09Z")

</div>

`Value == JSON` won't allow me to call `JSON.staticMethod()`. I'm not actually sure what the difference is between `T == P` and `T: P`. Can you elaborate on that for me?

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [April 19, 2021, 8:35pm UTC](https://forums.swift.org/t/another-value-of-protocol-type-cannot-conform-because-only-struct-enum-class-types-can-conform-to-protocols-post/47548/4 "2021-04-19T20:35:07Z")

</div>

`Value == JSON` is a same-type constraint, which means `Value` has to be exactly `JSON` and `Value: JSON` is a conformance constraint, which means `Value` has to be a concrete type that conforms to `JSON` (there are exceptions to it, like `Error` which self-conforms). In your dictionary example, `Value` is inferred to be `String` so other values need to be `String` as well. If you change it to `Value == JSON`, it compiles because you can have different types of values boxed/erased into `JSON`. It' effectively makes it a heterogenous dictionary, kind of like `[String: Any]`.

---

<div class="post-metadata">

**Author:** ![NSExceptional](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nsexceptional/32/6813_2.png) [@NSExceptional](https://forums.swift.org/u/NSExceptional)\
**Post date:** [April 19, 2021, 8:42pm UTC](https://forums.swift.org/t/another-value-of-protocol-type-cannot-conform-because-only-struct-enum-class-types-can-conform-to-protocols-post/47548/5 "2021-04-19T20:42:24Z")

</div>

I see. Is that similar to the difference between `some P` and `any P`?

Why does using `==` remove my ability to call static methods on `P`?

Edit: ~~Never mind, I just needed to change `dict.mapValues(Value.staticMethod())` to `dict.mapValues(staticMethod())` for some reason?~~

Edit 2: Okay so the above just ended up calling the method I was already in, never mind. I now understand when and why I would use `==` over `:`, thank you!

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [April 20, 2021, 4:44am UTC](https://forums.swift.org/t/another-value-of-protocol-type-cannot-conform-because-only-struct-enum-class-types-can-conform-to-protocols-post/47548/6 "2021-04-20T04:44:44Z")

</div>

> [@NSExceptional](#):
>
> ```swift
> protocol JSON { }
> extension String: JSON { }
> extension Int: JSON { }
> ... // and so on
> extension Array: JSON where Element: JSON { }
> extension Dictionary: JSON where Key == String, Value: JSON { }
> 
> ```

For future readers.

```swift
protocol JSON { }
extension String: JSON { }
extension Int: JSON { }
//.....
extension Array: JSON where Element == JSON { }
extension Dictionary: JSON where Key == String, Value == JSON { }

```
