Introduction: Why Do You Need to Know the Type of a Variable in Swift?
\nHave you ever been writing code in Swift and suddenly caught yourself thinking: "What type is this variable?" Especially when working with Any, generics, or complex inheritance hierarchies. It's like trying to guess what's inside a box without opening it. But Swift has powerful tools that allow you to look inside and accurately determine the type or class of a variable.
In this article, we will explore how to print the type of a variable in Swift using type(of:), Mirror, String(describing:), and even the good old dynamicType (yes, it's still alive in legacy code). You will learn not just to print the type, but also to use this in real projects: for debugging, logging, runtime type checking, and working with protocols.
This article is written for the educational website pythonlib.ru and is adapted for both beginners and experienced developers. Let's go!
\n\n1. The Simplest Way: type(of:)
\nThe most popular and correct way to find out the type of a variable in Swift is to use the global function type(of:). It returns the metatype (MetaType) of the passed value.
Example:
\nlet name = "Anna"\nlet age = 25\nlet price: Double = 99.99\nlet isActive = true\n\nprint(type(of: name)) // String\nprint(type(of: age)) // Int\nprint(type(of: price)) // Double\nprint(type(of: isActive)) // Bool\n\nNote: type(of:) works with any types — structures, classes, enumerations, closures. Even with optional values:
var optionalValue: String? = "Hello"\nprint(type(of: optionalValue)) // Optional<String>\n\n\nWhy is type(of:) the Best Choice?
\n- \n
- Works with value types (structures, enumerations) and reference types (classes). \n
- Supports protocols and generics. \n
- Does not require explicit type specification in code. \n
- Returns the exact dynamic type (takes inheritance into account). \n
2. The Classic Way: String(describing:)
\nSometimes you need not just to find out the type, but to convert it into a string for output to a log or interface. String(describing:) handles this task perfectly:
let value: Any = 42\nprint(String(describing: type(of: value))) // Int\n\nYou can combine it with type(of:) for nice logging:
func logType(_ value: Any) {\n let typeName = String(describing: type(of: value))\n print("[LOG] Type: \\(typeName), value: \\(value)")\n}\nlogType(3.14) // [LOG] Type: Double, value: 3.14\n\n\n3. Working with Classes: dynamicType and Mirror
\nBefore Swift 3, the dynamicType property was used. It is still available for backward compatibility, but is officially deprecated. However, you may encounter it in older projects:
class Animal {}\nclass Dog: Animal {}\n\nlet pet: Animal = Dog()\nprint(pet.dynamicType) // Dog (deprecated syntax)\n\nThe modern replacement is type(of:):
print(type(of: pet)) // Dog\n\n\nMirror: Looking Deeper
\nIf you need to find out not only the type but also the structure of an object (for example, property names), use Mirror:
struct User {\n let name: String\n let age: Int\n}\n\nlet user = User(name: "Ivan", age: 30)\nlet mirror = Mirror(reflecting: user)\nprint(mirror.subjectType) // User\nfor child in mirror.children {\n print("\\(child.label ?? ""): \\(child.value) (\\(type(of: child.value)))")\n}\n// Output:\n// name: Ivan (String)\n// age: 30 (Int)\n\nThis is especially useful for debugging complex hierarchies or when working with reflection.
\n\n4. Determining the Class for Any and AnyObject
\nIn Swift, the Any type is often encountered — it can store a value of any type. To find out the specific type