Downcasting AnyHashable to either String or Int

I have values that are typed as AnyHashable but I know they will either be a String or an Int. Is there a way to downcast correctly without knowing the specific type but knowing it will be one or type types?

func f(eitherIntOrString: AnyHashable) {
  if let str = eitherIntOrString as? String { 
    print("\(str) is a string") 
  } else if let int = eitherIntOrString as? Int { 
    print("\(int) is an Int") 
  } else {
    fatalError("It was neither Int or String")
  }
}

how would that function work if the return value is Void

You would just use the strings/ints where the print statements are.

If you need the values for a longer time, as String or Int, then you'll need to introduce either protocol (that you extend String and Integer), or a enum with two cases (each with an associated value, one with a string and one with an integer).

1 Like

Ah, are you trying to downcast into a single type that may be either String or Int (similar to union types in typescript), instead of downcasting to String or downcasting to Int?

There is no such thing in Swift, every variable has only a single type. The closest you can get is to either make a protocol that both of your types conform to, or an enum with associated values. Neither solution is very useful, because you don't know what you can do with a type that is simply one of two different unrelated types.

protocol EitherStringOrInt {}
extension Int: EitherStringOrInt {}
extension String: EitherStringOrInt {}

func f(eitherIntOrString: AnyHashable) -> EitherStringOrInt {
  return eitherIntOrString as! EitherStringOrInt
}
enum EitherStringOrInt {
    case int(Int)
    case string(String)
}

func f(eitherIntOrString: AnyHashable) -> EitherStringOrInt {
  if let str = eitherIntOrString as? String { 
    return .string(str)
  } else if let int = eitherIntOrString as? Int { 
    return .int(int)
  } else {
    fatalError("It was neither Int or String")
  }
}

@cukr that looks interesting. What about more complex types like Array<String> and [AnyHashable:Any] ?

Terms of Service

Privacy Policy

Cookie Policy