Swift
object type
type checking
programming
iOS development

How do you find out the type of an object in Swift?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Swift gives you several ways to inspect or narrow types at runtime, but each tool answers a slightly different question. Use is to test whether a value matches a type, as? to cast safely, and type(of:) when you want the runtime type itself for debugging or branching logic.

Check a Type with is

The is operator returns a boolean that tells you whether a value conforms to or inherits from a given type.

swift
1import Foundation
2
3let value: Any = "Hello"
4
5if value is String {
6    print("value is a String")
7}

This is the right choice when you only need to know whether a value matches a type and do not need the typed value yet.

Safely Cast with as?

In real Swift code, type checking usually leads straight into conditional casting. as? returns an optional and avoids a crash when the cast fails.

swift
1import Foundation
2
3let value: Any = "Hello"
4
5if let text = value as? String {
6    print(text.uppercased())
7} else {
8    print("Not a String")
9}

This is often better than a separate is check because it both tests the type and gives you the typed result.

Use as! Only When Failure Is Impossible

Force casting exists, but it is a runtime trap if your assumption is wrong.

swift
1import Foundation
2
3let value: Any = "Hello"
4let text = value as! String
5print(text)

Use this only when the surrounding program logic guarantees the type. In most application code, as? is safer and easier to maintain.

Inspect the Runtime Type with type(of:)

If you need the concrete type for logging or debugging, type(of:) returns it directly.

swift
1import Foundation
2
3let number = 42
4print(type(of: number))

This is useful when values are stored as Any, protocol types, or superclass references and you want to see the actual runtime type.

Combine Type Checks in switch

For heterogeneous collections, switch often produces the clearest code.

swift
1import Foundation
2
3let items: [Any] = [1, "hello", 3.14, true]
4
5for item in items {
6    switch item {
7    case is Int:
8        print("Int")
9    case is String:
10        print("String")
11    case is Double:
12        print("Double")
13    case is Bool:
14        print("Bool")
15    default:
16        print("Unknown")
17    }
18}

This reads better than a chain of repeated if statements once the number of candidate types grows.

Check Protocol Conformance Too

Sometimes the question is not the concrete class, but whether the value supports a capability. Protocol casting works the same way as type casting.

swift
1import Foundation
2
3protocol Greetable {
4    func greet()
5}
6
7struct Greeter: Greetable {
8    func greet() {
9        print("Hello")
10    }
11}
12
13let value: Any = Greeter()
14if let greetable = value as? Greetable {
15    greetable.greet()
16}

That is usually more flexible than checking for one exact concrete type.

Prefer Strong Types Over Runtime Inspection

Frequent runtime type checks can signal that the model is too weakly typed. If many values live as Any, you may be fighting the language instead of using it. Swift works best when types are explicit and the compiler can help you, so treat runtime inspection as a targeted tool, not a default design style.

Common Pitfalls

  • Using as! where a failed cast is possible and turning bad input into a crash.
  • Calling type(of:) when the real need is a safe cast to a usable type.
  • Overusing Any and then compensating with repeated runtime checks.
  • Checking concrete classes when protocol conformance would be the better abstraction.
  • Splitting type checks and casts into separate steps when as? can do both cleanly.

Summary

  • Use is for a simple type test.
  • Use as? for safe casting and typed access.
  • Use as! only when the cast cannot fail.
  • Use type(of:) for runtime inspection and debugging.
  • Prefer stronger compile-time types so runtime checks stay minimal.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions