Thursday, March 16, 2023

Passing Types to Swift Functions

Paul Samuels:

This post uses a toy helper function that fetches remote JSON to show how we can design its api so that explicitly providing the type isn’t required when the compiler can infer types from context.


We can look at how JSONDecode.decode is defined to see how its api is designed. Clicking through the header we see

open func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable

This is nothing new, but I wanted to document it here because I did not find this pattern obvious when I first learned it. My instinct from Objective-C was to pass in an AnyClass or perhaps an Any.Type, but that doesn’t work because there’s no way to convince the compiler that the return value will match the type received at runtime.

So you have to use generics. You could omit the type parameter and have the compiler infer T based on how the call site uses the return value, but that feels kind of backwards. Instead, using T.Type lets you go the other way and have T inferred from the parameter. This makes more sense, though it’s still a bit weird because you are passing in type but don’t really need it at runtime since you already have T.self.

With the latest change we have more flexibility but if feels like we’ve lost some brevity in cases where the compiler can infer things. To bring this type inference back we can use a default argument[…]

Comments RSS · Twitter · Mastodon

Leave a Comment