# Enforce any existential to have a value conforming to a certain protocol

**URL:** <https://forums.swift.org/t/enforce-any-existential-to-have-a-value-conforming-to-a-certain-protocol/69817>\
**Category:** Using Swift\
**Tags:** generics, protocols, existential\
**Created:** [February 3, 2024, 8:25pm UTC](https://forums.swift.org/t/enforce-any-existential-to-have-a-value-conforming-to-a-certain-protocol/69817 "2024-02-03T20:25:06Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![GeorgeElsham](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/georgeelsham/32/43452_2.png) [@GeorgeElsham](https://forums.swift.org/u/GeorgeElsham)\
**Post date:** [February 3, 2024, 8:25pm UTC](https://forums.swift.org/t/enforce-any-existential-to-have-a-value-conforming-to-a-certain-protocol/69817/1 "2024-02-03T20:25:06Z")

</div>

# About

I would like to be able to enforce that some existential conforms to a specific protocol. This question relates to an existing package I am developing, which uses a sub-par solution, due to reduced compile time safety as I haven't found a way to express this within the Swift type system.

This post will use a SwiftUI example for demonstration purposes to give more context, but this is not dependent on SwiftUI. This post is a very simplied version of the problem I'm having.

# Aim

I aim to have my package have full safety enforced by the type system. I will refer to the user side of the package as the "client". Requirements:

1. The code in the framework should not (and will not) have access to protocols defined by the client.
2. We use type safety instead of runtime checks.

Below is some code of what I expect the result to look like:

```swift
import SwiftUI

// Package
struct Tree<ID: Hashable>: View {
    @Binding private var element: any Identifiable<ID>

    init(element: Binding<any Identifiable<ID>>) {
        _element = element
    }

    var body: some View {
        Text("ID: \(element.id)")
    }
}

// Client
protocol MyElement: Identifiable<UUID> {}

struct El1: MyElement {
    let id = UUID()
}
struct El2: MyElement {
    let id = UUID()
}

struct ContentView: View {
    @State private var element: any MyElement = El1()

    var body: some View {
        Tree(element: $element)
    }
}

```

This gives the following errors in the `ContentView` body:

> Cannot convert value of type 'Binding' to expected argument type 'Binding\<any Identifiable\>'

> Generic parameter 'ID' could not be inferred

Explicitly specifying the `ID` fixes the second error, but still not the first.

# Current solution

We've seen what I aim for. Here's what I currently have, which does in fact work:

```swift
import SwiftUI

// Package
struct Tree<ID: Hashable>: View {
    @Binding private var element: any Identifiable<ID>

    init<T>(element: Binding<T>) {
        precondition(element.wrappedValue is any Identifiable<ID>, "Element is of wrong type")

        _element = Binding(
            get: { element.wrappedValue as! any Identifiable<ID> },
            set: { element.wrappedValue = $0 as! T }
        )
    }

    var body: some View {
        Text("ID: \(element.id)")
    }
}

// Client
protocol MyElement: Identifiable<UUID> {}

struct El1: MyElement {
    let id = UUID()
}
struct El2: MyElement {
    let id = UUID()
}

struct ContentView: View {
    @State private var element: any MyElement = El1()

    var body: some View {
        Tree<UUID>(element: $element)
    }
}

```

It has several downsides:

1. The `ID` type is explicitly required, even though `MyElement` defines the `ID`.
2. Any type can be used in place of `T`, and so the `precondition` only catches issues at run time.

# Solution

What's the solution to this? Does it currently exist within the Swift type system to express that an `any` existential should have a value conforming to a certain protocol?
