Dynamic casting Any to a runtime optional type

We can use this answer from the thread Challenge: Flattening nested optionals:

protocol Flattenable {
  func flattened() -> Any?
}

extension Optional: Flattenable {
  func flattened() -> Any? {
    switch self {
    case .some(let x as Flattenable): return x.flattened()
    case .some(let x): return x
    case .none: return nil
    }
  }
}

To write a function like this:

func flatten(_ a: Any) -> Any? {
  return (a as? Flattenable)?.flattened()
}

And then you can use:

for p in [aa, bb] {
    print(flatten(p) == nil ? "NIL" : "Non Nil")
}

• • •

If you just want the boolean result, you could do:

func isActuallyNil(_ a: Any) -> Bool {
  return (a as? Flattenable)?.flattened() == nil
}

Or if you want to extract the innermost wrapped type into an Any.Type, that can be done using the solutions from Challenge: Finding base type of nested optionals.

1 Like