DevPrep

All topics › Modern Swift

What is typed throws (Swift 6)?

Senior PRO

The idea

Typed throws (SE-0413, Swift 6.0) let you state a concrete error type in the signature: func parse() throws(ParseError) -> Int. Before, throws always meant any Error: catch received an existential, and to enumerate the cases you needed as? ParseError casts plus a mandatory "something else" branch.

Equivalences: plain throws = throws(any Error); a non-throwing function = throws(Never). So old code is unchanged, and rethrows can in many cases be expressed through a generic error parameter.

enum ParseError: Error { case empty, invalid(String) }

func parse(_ s: String) throws(ParseError) -> Int {
    guard !s.isEmpty else { throw .empty }
    guard let n = Int(s) else { throw .invalid(s) }
    return n
}

do {
    _ = try parse("x")
} catch {                          // error: ParseError, not any Error
    switch error {                 // exhaustive switch without default
    case .empty: print("empty")
    case .invalid(let s): print("invalid", s)
    }
}

// Generic error propagation instead of rethrows
func firstMap<T, U, E: Error>(
    _ xs: [T], _ f: (T) throws(E) -> U
) throws(E) -> U? {
    guard let x = xs.first else { return nil }
    return try f(x)
}
let r: Int? = try? firstMap(["7"]) { s throws(ParseError) in try parse(s) }
print(r ?? -1)   // 7

The rest of this answer, with code and interview follow-ups, is in the DevPrep app.

Read the full answer in DevPrep

Practice this before your interview

DevPrep turns these answers into one-minute challenges: what does this code print, find the bug, mock interviews. One challenge a day.

Get DevPrep on the App Store