How does propertyWrapper composition work vis-à-vis SwiftUI @Environment(\.presentationMode) @Binding?

When you compose property wrappers, the next property wrapper in the chain becomes the wrapped value of the previous property wrapper. The wrapped property itself represents the wrapped value of the innermost property wrapper. Type inference will iterate over the chain of property wrapper attributes, equating the wrapped-value type of the previous property wrapper with the type of the next property wrapper.

So, for this example:

@Environment(\.presentationMode) @Binding var presentationMode2

Type inference starts with the outermost property wrapper, which is @Environment. It will then equate the wrapped-value type of Environment with the type of the next property wrapper, which is Binding. The wrapped value type of Environment is determined by the key-path value type (in this case, the type of EnvironmentValues.presentationMode), which is Binding<PresentationMode>. When the compiler equates this wrapped-value type with the next property wrapper, the generic argument for @Binding is inferred to be PresentationMode. Then, the type of the property can be inferred as the wrapped-value type of Binding<PresentationMode>, which is PresentationMode.

6 Likes