Determine if Any.Type is Optional
Assuming that what you are trying to do is something like this:
let anyType: Any.Type = Optional<String>.self
anyType is Optional<Any>.Type // false
Sadly swift currently (as of Swift 2) does not support covariance nor contravariance and type checks directly against Optional.Type
cannot be done:
// Argument for generic parameter 'Wrapped' could not be inferred
anyType is Optional.Type // Causes error
An alternative is to make Optional
extend an specific protocol, and check for that type:
protocol OptionalProtocol {}
extension Optional : OptionalProtocol {}
let anyType: Any.Type = Optional<String>.self
anyType is OptionalProtocol.Type // true
How can you check if a type is Optional in Swift?
This is a hacky but working solution:
func isOptional(_ type: Any.Type) -> Bool {
let typeName = String(describing: type)
return typeName.hasPrefix("Optional<")
}
Test:
let t1 = Int?.self
let t2 = Bool.self
print(isOptional(t1))
// true
print(isOptional(t2))
// false
Given a Swift `Any` type can I determine if it's an `Optional`?
You can use runtime introspection using Mirror
:
let foo: String? = "foo"
let bar: String = "bar"
var a: Any = foo
// if wrapping an optional, the reflection of the value has
// a displaystyle "optional"
if let displayStyle = Mirror.init(reflecting: a).displayStyle {
print(displayStyle) // optional
}
// for a non-optional fundamental native type: no displaystyle
a = bar
if let displayStyle = Mirror.init(reflecting: a).displayStyle {
print(displayStyle)
} // prints nothing
Optional/non-optional example where the underlying type is user-defined (non native):
struct Foo {}
let foo: Foo? = Foo()
let bar: Foo = Foo()
var a: Any = foo
// if wrapping an optional, the reflection of the value has
// a displaystyle "optional"
if let displayStyle = Mirror(reflecting: a).displayStyle {
print(displayStyle) // optional
}
// for a non-optional non-fundamental type:
a = bar
if let displayStyle = Mirror(reflecting: a).displayStyle {
print(displayStyle) // struct
}
If you don't want need to use the binded displayStyle
variable (e.g. for printing) but simply want check whether the wrapped value is any kind of optional, you can add a boolean clause to the if
statement that holds the optional binding of the displayStyle
case,
if let displayStyle = Mirror(reflecting: a).displayStyle,
displayStyle == .optional {
// is an optional ...
}
... or remove the binding entirely in favour of a single conditional expression using the nil coalescing operator (??
)
if Mirror(reflecting: a).displayStyle ?? .class == .optional {
// is an optional
}
Note however that for all the methods above, this simply tells you as dev whether the type wrapped by the Any
instance is optional or not: Swifts typing system still knows nothing of the sort.
What is the type of a Java empty Optional?
The Optional
class is a container that might contain a specific element. As such, it has two concepts:
- The type it might contain
- The actual object it contains
The type it might contain is specified trough generics. Generics only exist at compile time and are lost at runtime.
To answer your questions:
- When using an
Optional
, you usually define it to possibly contain a type, like this:
Optional<String> optionalString;
At this point we know that optionalString
might contain a String. If we do this:
Optional<String> optionalString = Optional.empty();
It doesn't actually contain anything, but we can use it anywhere an Optional<String>
is required.
- The type of the
Optional
is inferred trough its usage. Like above, you specify theOptional.empty()
to be anOptional<String>
. You can also specify its type trough the return value of a method, like so:
public Optional<Integer> findNumber() {
return Optional.empty();
}
- Since the type is no longer present at runtime, there is no way to check what the optional contains at this point. At runtime, an empty
Optional
has no type.
typescript exclude optional fields from type (deep)
With this recursive type:
type OnlyRequired<T> =
T extends object
? { [K in keyof T as {} extends Pick<T, K> ? never : K]: OnlyRequired<T[K]> }
: T;
If T
is a primitive, we don't need to do anything. However if it is an object we have to go through each key and get only the ones that can't be optional (credit to @jcalz) and then recursively gets only required keys of T[K]
.
Note that functions need a little special handling and checking for undefined
is not exhaustive or the best way to check for optional properties but it does work for your example.
Playground
Related Topics
What Is the Correct Date.Format for Mmm Dd, Yyyy Hh:Mm:Ss A? and How Convert to Dd-Mm-Yyyy Hh:Ii
Draw Scenekit Object Between Two Points
How to Connect to Self Signed Servers Using Alamofire 1.3
How to Make #Selector Refer to a Closure in Swift
How to Print Out the Method Name and Line Number in Swift
Uitableview Load More When Scrolling to Bottom
Scanning Real-World Object and Generating 3D Mesh from It
Swift: Setting an Optional Property of a Protocol
Swift Turn a Country Code into a Emoji Flag via Unicode
Rounding in Swift with Round()
Convert Uiimage to Grayscale Keeping Image Quality
Sort Array by Calculated Distance in Swift
Round Up Double to 2 Decimal Places
How to Save a Struct to Realm in Swift
Thread Safe Singleton in Swift
How to "Strongify" Optional Self Using Guard in Swift 2.0
Do Capture Lists of Inner Closures Need to Redeclare 'Self' as 'Weak' or 'Unowned'