My question is simply as the title states. I want to take some View, apply a view modifier to it, and still be able to keep it as that original type instead of it becoming a some View.
Say we have a simple view like this:
struct SomeView: View {
    let image: Image
    var body: some View {
        image
    }
}
In the PreviewProvider, we can test this out with a system image from SF Symbols:
struct SomeView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            SomeView(image: Image.init(systemName: "pawprint"))
                .previewDisplayName("pawprint")
        }
        .previewLayout(.sizeThatFits)
    }
}
And it works:

Now let's try to add a second preview using the same SF Symbol but applying the .font view modifier to increase the size:
    static var previews: some View {
        Group {
            SomeView(image: Image.init(systemName: "pawprint"))
                .previewDisplayName("SomeView pawprint")
            // Error: Cannot convert value of type 'some View' to expected argument type 'Image'
            SomeView(image: Image.init(systemName: "pawprint").font(.system(size: 64)))
                .previewDisplayName("SomeView bigPawprint")
        }
        .previewLayout(.sizeThatFits)
    }
Yep, that's about right, because the view modifier .font returns the opaque type some View. But if we apply the "Fix-it button" suggestion to force-cast (sure, let's do that, for science), then it compiles, but crashes the previewer. Also crashes if we try to run in a simulator, so it's not just a Previewer bug.
And yet, there's no problem at all just displaying it as some View:
        Group {
            SomeView(image: Image.init(systemName: "pawprint"))
                .previewDisplayName("SomeView pawprint")
            // Crashes
            // SomeView(image: Image.init(systemName: "pawprint").font(.system(size: 64)) as! Image)
                .previewDisplayName("SomeView big pawprint")
            // Works
            Image.init(systemName: "pawprint").font(.system(size: 64))
                .previewDisplayName("View Modifier big pawprint")
        }
        .previewLayout(.sizeThatFits)

So, how can I do something like this on a View where I apply a view modifier, but I can still use the original View type?
No. And because most of the view modifier types are unknown to us (such as whatever backs the font modifier), you'll have to emulate ModifiedContent using a closure, not a Modifier instance.
struct SomeView<ModifiedImage: View>: View {
  let image: Image
  let modify: (Image) -> ModifiedImage
  var body: some View {
    modify(image)
  }
}
extension SomeView where ModifiedImage == Image {
  init(image: Image) {
    self.init(image: image) { $0 }
  }
}
SomeView(image: .init(systemName: "pawprint"))
  .previewDisplayName("SomeView pawprint")
SomeView(image: .init(systemName: "pawprint")) {
  $0.font(.system(size: 64))
}
.previewDisplayName("SomeView bigPawprint")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With