I think your best option is to contain the damage in Utils by renaming the function:
import SDK
extension SDK.Foo {
#if swift(>=4.1.50)
public func myFoo(...) { self.foo(...) }
#else
public func myFoo(...) { ... } // Method available only in swift 4.2
#endif
}
In general the kind of "polyfill" technique you're describing isn't well-supported in Swift, but it's questionable whether we want to encourage that pattern (based on static checks or dynamic checks). Here's an old discussion about some of the pros and cons, though in a dynamic-checking context.