Type Casting (is, as?)
Discover and convert types at runtime: check a type with is , safely downcast with as? , force a cast with as! , and work with the catch-all Any and AnyObject types.
Learn Type Casting (is, as?) in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ Checking Types with is
The is operator answers a yes/no question: is this instance of that type? It returns a Bool , so it's perfect for counting or filtering without converting anything.
2️⃣ Downcasting with as? and as!
Downcasting converts a general type to a more specific one. The safe form, as? , returns an optional — the value on success, nil on failure — so pair it with if let . The forced form, as! , returns the value directly but crashes if the cast fails, so only use it when you're certain.
3️⃣ Any / AnyObject and Downcasting in a switch
Any can hold a value of any type; AnyObject holds only class instances. To work with a mixed collection, discover each element's real type by downcasting inside a switch using case let x as Type: .
Your turn. Fill in the type-check and conditional-cast operators.
📋 Quick Reference
No blanks this time — just a brief and an outline. Use a switch with downcasting cases to describe each shape.
Practice quiz
What does the 'is' operator check?
- Whether a value can be cast and returns the cast value
- Whether two values are equal
- Whether an instance is of a certain type, returning a Bool
- Whether a value is nil
Answer: Whether an instance is of a certain type, returning a Bool. 'is' is the type-check operator: it returns true or false depending on the instance's type.
What does the 'as?' operator return?
- An optional — the cast value if it succeeds, or nil if it fails
- The cast value, or a crash on failure
- Always nil
- A Bool
Answer: An optional — the cast value if it succeeds, or nil if it fails. 'as?' is the conditional cast; it returns an optional that is nil when the cast can't succeed.
What happens with 'as!' if the cast fails at runtime?
- It returns nil
- It returns false
- It returns the original value
- It crashes the program
Answer: It crashes the program. 'as!' is the forced cast — it crashes if the downcast is not actually possible.
Which cast is safest to use when you are not certain of the type?
- as!
- as?
- is
- as
Answer: as?. Use 'as?' (conditional cast) when unsure; it returns nil instead of crashing.
What is the difference between Any and AnyObject?
- Any can hold any type including value types; AnyObject only holds class instances
- They are identical
- AnyObject holds any type; Any only holds classes
- Any only holds Ints
Answer: Any can hold any type including value types; AnyObject only holds class instances. Any represents an instance of any type at all; AnyObject represents an instance of any class type.
When downcasting in a switch statement, which keyword pattern is used?
- is only
- case x is SomeType:
- case let x as SomeType:
- cast SomeType
Answer: case let x as SomeType:. In a switch you write 'case let x as SomeType:' to bind the downcast value.
Is 'as' (without ? or !) ever used, and for what?
- Never
- For guaranteed conversions like upcasting or bridging that always succeed
- Only for optionals
- Only in switch
Answer: For guaranteed conversions like upcasting or bridging that always succeed. Plain 'as' is for casts the compiler knows always succeed, such as upcasting to a superclass.
Given 'let things: [Any] = [1, "hi", 3.0]', how do you safely treat an element as a String?
- thing as String
- thing as! Int
- thing is String only
- if let s = thing as? String { }
Answer: if let s = thing as? String { }. 'as?' with optional binding safely extracts the String when the element actually is one.
What does 'value is String' evaluate to when value holds an Int?
- true
- false
- nil
- It crashes
Answer: false. 'is' returns false when the instance is not of the checked type.
Why use 'as?' over 'as!' for values from a heterogeneous collection?
- as? is faster
- as! returns nil
- as? lets you handle the non-matching case gracefully instead of crashing
- There is no difference
Answer: as? lets you handle the non-matching case gracefully instead of crashing. With mixed types you can't guarantee the cast, so as? avoids the crash that as! would cause on a mismatch.