Type placeholders were recently introduced in Swift 5.6. And yes, they are a nice add-on to powerful Swift type inference system. If you are familiar with C++, you must know about an auto keyword. Type placeholders are almost the same.
Generics and type placeholder
let number: _ = 42 // Type placeholder
let anotherNumber = 42Yes, Swift can infer variable's type, but type placeholders mean to be used for a type with multiple types in it. Generics. That's where they really shine.
Consider regular Result enum
enum Result<Success, Failure> where Failure : Error {
case success(Success)
case failure(Failure)
}And what if we have some kind of complex object
var ohMy = [1: [3: (1, 2, 3, "That's a long tuple")]]If you will try to create a Result from ohMy, you'll see compilation error.
let result = Result.success(ohMy)Failure could not be inferredBruh. So I need to write...
let result = Result<[Int : [Int : (Int, Int, Int, String)]], Error>.success(ohMy)Thanks to type placeholders, no. Swift can infer object's type by itself. So, we need to provide Failure type only.
let result = Result<_, Error>.success(ohMy) // Nice
Subscribe to Alex Dremov
Get the email newsletter and receive valuable tips to bump up your professional skills
Collections and type placeholder
This feature also useful with collections. What if we need a dictionary with enum keys?
enum Foo {
case bizz
case bonk
}
let results = [
.bizz: ohMy,
.bonk: ohMy
]bizz cannot be resolved without a contextual typeSo, let's provide this contextual type, but you remember how ohMy's type is bad-looking? Let's use type placeholder.
// 🚫
let results:[Foo: [Int : [Int : (Int, Int, Int, String)]]] = [
.bizz: ohMy,
.bonk: ohMy
]
// ✅
let results:[Foo: _] = [
.bizz: ohMy,
.bonk: ohMy
]More examples
Examples of types containing placeholders are:
Array<_> // array with placeholder element type
[Int: _] // dictionary with placeholder value type
(_) -> Int // function type accepting a single type placeholder argument and returning 'Int'
(_, Double) // tuple type of placeholder and 'Double'
_? // optional wrapping a type placeholderFinal notes
That's a great feature and broadens Swift’s type inference capabilities. For now, it's some kind of less-known, but I think it will be more used in the future.
You can check out other less-known Swift features in my previous post:




