Any info on the _typeEraser attribute

We have seen the introduction of the @_typeEraser attribute in the compiler codebase in February.
And it seems now that it will be used in SwiftUI by being able to type erase concrete View type to AnyView.

Do we have more info on what will be the use case?

1 Like

The purpose of the @_typeEraser attribute is to allow functions with opaque return types constrained by certain protocols to be dynamically replaced with implementations that have different underlying types. Normally, if you write something like:

var body: some View { MyView() }

then the underlying type of body is fixed to MyView. Even if body is tagged dynamic, then @_dynamicReplacements for the body would still have to return the same MyView type in order to remain compatible. This is too restrictive for Xcode Previews, where we want users to be able to modify their SwiftUI views arbitrarily, and dynamically reload the new implementation in place. So, if the protocol constraint on a dynamic declaration's opaque type has an associated @_typeEraser, we use that @_typeEraser to implicitly wrap the opaque return type, so that even though you wrote MyView() above, the implementation is compiled as:

dynamic var body: some View { AnyView(MyView()) }

So the underlying type of the opaque type is AnyView. If you later modify body to return TheirView() instead, it will also be wrapped in AnyView, so the underlying type of the opaque type is not changed.

17 Likes

Wow nice design trick. Nowadays, Swift already have amount of @attrs; it's not easy to understand and remember all of them for new users of the language.

It’s an underscored attribute so it’s not meant for public use (and should be hidden in code completion, etc).

3 Likes

Yeah, in its current form, none of this is yet stable officially-supported functionality; it's primarily an implementation detail of Xcode Previews.

2 Likes

Another use case I would like to explore, is the ability to mock methods that return opaque types in testing.

Does this attribute work with generics and if so how?