# Is there any way to specify a generic type which is constrained to either a type or an optional type?

**URL:** <https://forums.swift.org/t/is-there-any-way-to-specify-a-generic-type-which-is-constrained-to-either-a-type-or-an-optional-type/30313>\
**Category:** Using Swift\
**Created:** [October 30, 2019, 8:48am UTC](https://forums.swift.org/t/is-there-any-way-to-specify-a-generic-type-which-is-constrained-to-either-a-type-or-an-optional-type/30313 "2019-10-30T08:48:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Spencer\_Kohan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/spencer_kohan/32/4505_2.png) [@Spencer\_Kohan](https://forums.swift.org/u/Spencer_Kohan)\
**Post date:** [October 30, 2019, 8:48am UTC](https://forums.swift.org/t/is-there-any-way-to-specify-a-generic-type-which-is-constrained-to-either-a-type-or-an-optional-type/30313/1 "2019-10-30T08:48:51Z")

</div>

So let's say I want to implement a property wrapper which operates on either Bool or Bool?. For instance, something like this:

```
@propertyWrapper
struct BoolWrapper<Value: Some constraint here?> {
    var wrappedValue: Value
    ...
}

```

So that it can be used in either of these ways:

```
@BoolWrapper var foo: Bool = true
@BoolWrapper var bar: Bool? = nil

```

But not with any type which _is not_ Bool or Bool?

Is there any way to express this?

---

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [October 30, 2019, 9:21am UTC](https://forums.swift.org/t/is-there-any-way-to-specify-a-generic-type-which-is-constrained-to-either-a-type-or-an-optional-type/30313/2 "2019-10-30T09:21:24Z")

</div>

Yes.

Start from the beginning: the [only expressible constraints](https://docs.swift.org/swift-book/LanguageGuide/Generics.html#ID186) for generic types in Swift are protocol conformances, subclassing, and combination of those:

```swift
struct MyGenericType<T: SomeProtocol> { ... }
struct MyGenericType<T: SomeClass> { ... }
struct MyGenericType<T: SomeClass & SomeProtocol> { ... }

```

`Bool` and `Bool?` are not related in any way by subclassing. The only remaining solution is thus protocol conformance.

So let's define a protocol that only Bool and Bool? conform to!

```swift
protocol Boolish { /* any useful common methods here */ }
extension Bool: Boolish { }
extension Optional: Boolish where Wrapped == Bool { }

@propertyWrapper
struct BoolWrapper<Value: Boolish> {
    var wrappedValue: Value
}

struct Container {
    @BoolWrapper var foo: Bool = true
    @BoolWrapper var bar: Bool? = nil
    
    // Error: Referencing initializer 'init(wrappedValue:)' on 'BoolWrapper'
    // requires that 'String' conform to 'Boolish'
    // @BoolWrapper var baz: String = ""
}

```

Swift won't let you restrict Boolish conformance on Bool and Bool? only, though. You may have to explicitly document that no other types should adopt this protocol.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [October 30, 2019, 2:16pm UTC](https://forums.swift.org/t/is-there-any-way-to-specify-a-generic-type-which-is-constrained-to-either-a-type-or-an-optional-type/30313/3 "2019-10-30T14:16:32Z")

</div>

> [@gwendal.roue](#):
>
> Start from the beginning: the [only expressible constraints](https://docs.swift.org/swift-book/LanguageGuide/Generics.html#ID186) for generic types in Swift are protocol conformances, subclassing, and combination of those

For now. My pitch for [generalized supertype constraints](https://forums.swift.org/t/generalized-supertype-constraints/22380) was well received. We just can't move it forward until somebody volunteers to work on implementation. If / when that happens the compiler would recognize the `Bool: Bool?` relationship in a generic constraint.

> [@gwendal.roue](#):
>
> Swift won't let you restrict Boolish conformance on Bool and Bool? only, though. You may have to explicitly document that no other types should adopt this protocol.

Also for now. Hopefully we can express closed protocols in the language eventually. This has been the topic of several threads in the past.

---

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [October 30, 2019, 2:24pm UTC](https://forums.swift.org/t/is-there-any-way-to-specify-a-generic-type-which-is-constrained-to-either-a-type-or-an-optional-type/30313/4 "2019-10-30T14:24:24Z")

</div>

Yes. The question was framed against the current state of the language, so I did not think it was useful to raise the complexity of the answer, and transform curiosity into mourning of unborn futures. _Today_ I believe my answer is correct, complete, and actionable.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [October 30, 2019, 2:42pm UTC](https://forums.swift.org/t/is-there-any-way-to-specify-a-generic-type-which-is-constrained-to-either-a-type-or-an-optional-type/30313/5 "2019-10-30T14:42:29Z")

</div>

> [@gwendal.roue](#):
>
> _Today_ I believe my answer is correct, complete, and actionable.

Absolutely. I just wanted to add the context that there may be other options in the future.
