Skip to content
tezvyn:
Menu

Swift Existential Types: The Polymorphism Box

MediumHow cards are made

An existential type is a boxed protocol: you see the interface, not the concrete type inside. Use it to store mixed concrete types behind one protocol, like [any Logger]. Prefer generics; existentials hide types and add dynamic dispatch overhead.

Why it exists

Swift prefers compile-time type knowledge for performance and safety. However, real programs often handle values whose concrete types are unknown until runtime, such as decoding network payloads or storing mixed view models. Existential types let the compiler enforce a protocol contract while erasing the specific concrete type, enabling polymorphism without forcing every call site to know every implementation upfront.

The mental model

Think of an existential as a shipping box with a capability label. The label says what the contents can do, but you cannot see inside. You can hand the box around and call its advertised methods, yet you lose the ability to know exactly what is inside. The box also takes more room than the raw item because it carries the label and padding.

How it works

When you assign a concrete value to an existential type, the Swift runtime wraps it in a container. This container holds the value, either inline or on the heap if large, plus witness tables for method dispatch and type metadata. Every call goes through dynamic dispatch rather than compile-time specialization. In modern Swift, you write this explicitly with the any keyword, making the boxing operation visible.

When to use it

Reach for an existential when you need heterogeneity at the storage level. Three signals are first, an array or dictionary holding multiple concrete types behind one protocol, second, a function returning different concrete types at runtime where opaque types fail, and third, type-erasing wrappers that hide complex associated types. The existential acts as a boundary so you stop propagating generic parameters through every layer.

When not to use it

Avoid existentials when a generic or some type would suffice. Generics let the compiler monomorphize code, eliminating dynamic dispatch and enabling stack allocation. Existentials cannot satisfy protocol conformance themselves, meaning any P does not conform to P, so you cannot pass one into a generic function expecting T: P without opening it. If your code handles one concrete type but merely hides the name, use an opaque some type instead.

One canonical example

Imagine a telemetry system where each feature team defines its own analytics event struct conforming to an AnalyticsEvent protocol with a send method. The central manager cannot know every concrete event type at compile time because new features add events weekly. The manager stores an array of any AnalyticsEvent. When flushing, it iterates and calls send on each boxed event. The manager sees only the protocol interface, while the runtime dispatches each call to the correct concrete implementation. This keeps the manager decoupled from every feature module.

Interview question

When is using an existential type (any P) preferable to using a generic (T: P) in Swift?

  • a.When the concrete type is known at compile time but should be hidden from callers
  • b.When you need to store multiple different concrete types conforming to P in the same collectionCorrect
  • c.When you want the compiler to monomorphize code for maximum performance
  • d.When you need to pass the boxed value into a generic function expecting T: P
Why?

Existentials excel when you need heterogeneity, like storing mixed concrete types in a single collection. If the concrete type is known at compile time and you only want to hide its name, Swift's opaque some type is the better choice, not an existential.

Just read this? Test yourself on what you have been reading.

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on swift — each one lists the topics its interview covers.

See open roles