Swift Tuples and Type Aliases

Tuples group a handful of values together without creating a new named type, and type aliases give an existing type a clearer, shorter name.

Grouping Values with Tuples

A tuple bundles multiple values into a single compound value, and the values inside don't need to be of the same type. You can access tuple elements by position using dot syntax like .0 and .1, or, more readably, by giving each element a name when you create the tuple. Tuples are especially handy for representing a small, temporary grouping of data that doesn't need the overhead of a dedicated struct.

Creating and accessing a tuple

let httpStatus = (code: 404, message: "Not Found")

print(httpStatus.code)      // 404
print(httpStatus.message)   // Not Found

let (code, message) = httpStatus
print("\(code): \(message)")   // 404: Not Found

Returning Multiple Values from Functions

Swift functions can only declare a single return type, but tuples make it easy to return several related values at once without wrapping them in a custom struct. This is a common pattern for functions that compute more than one result from the same pass over data, such as finding both the minimum and maximum of an array in a single loop.

A function returning a tuple

func minMax(of numbers: [Int]) -> (min: Int, max: Int)? {
    guard let first = numbers.first else { return nil }
    var currentMin = first
    var currentMax = first

    for number in numbers[1...] {
        if number < currentMin { currentMin = number }
        if number > currentMax { currentMax = number }
    }
    return (currentMin, currentMax)
}

if let bounds = minMax(of: [8, 3, 19, 1, 12]) {
    print("min: \(bounds.min), max: \(bounds.max)")   // min: 1, max: 19
}

Simplifying Types with typealias

As tuple types and closure types grow more descriptive, their full spelling can get unwieldy to repeat everywhere. A typealias declaration lets you attach a shorter, more meaningful name to any existing type, including tuples and closures, without creating a distinct type of its own — it's purely a naming convenience the compiler substitutes at compile time.

Naming tuple and closure types

typealias Coordinate = (latitude: Double, longitude: Double)
typealias CompletionHandler = (Bool, String?) -> Void

let hyderabad: Coordinate = (latitude: 17.385, longitude: 78.4867)

func fetchData(completion: CompletionHandler) {
    completion(true, nil)
}

fetchData { success, error in
    print(success ? "Done" : (error ?? "Unknown error"))
}
  • Reach for a tuple when grouping a few values briefly, usually as a function's return type
  • Reach for a struct when the group needs identity, methods, or gets passed around widely
  • Reach for typealias to give a tuple or closure signature a clear, reusable name
  • Name tuple elements (code:, message:) so call sites read clearly instead of using .0, .1
ConstructPurposeExample
TupleGroup a few related values temporarily(Int, String)
typealiasGive an existing type a shorter or clearer nametypealias ID = String
StructModel a reusable named type with behaviorstruct User { let id: String }
Note: Tuples are structural types, not nominal types: two tuple types are considered identical if their element types and labels match, regardless of where they were declared. This differs from structs, where two declarations with identical properties are still distinct, unrelated types.

Exercise: Swift Tuples

How do you access an element of an unnamed tuple like let point = (3, 5)?