Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The is operator is a binary type-checking operator used to perform dynamic type evaluation at runtime. It evaluates whether an instance’s underlying dynamic type matches a specific concrete type, is a subclass of a specified class type, conforms to a designated protocol, or matches a specific metatype. It returns a Boolean value (true if the type check succeeds, false otherwise).
expression is Type

Technical Mechanics

The is operator evaluates the runtime type metadata of the expression against the specified Type. It does not cast, mutate, or rebind the instance to a new type (unlike the as? or as! operators); it strictly performs a boolean evaluation. Concrete Types and Existentials When an expression is statically typed as an existential (such as Any or a protocol type), the is operator checks if the underlying dynamic type exactly matches a specific concrete value type (like a struct or enum).
let value: Any = 5

let isInteger = value is Int    // true: the underlying dynamic type is Int
let isString = value is String  // false: the underlying dynamic type is not String
Class Hierarchies When applied to class instances masked by an existential or a superclass static type, the operator evaluates to true if the instance’s dynamic type is exactly Type or a subclass of Type. It evaluates to false if the instance is a superclass or an entirely unrelated type in the inheritance tree.
class Base {}
class Derived: Base {}
class Unrelated {}

let instance: Any = Derived()

let check1 = instance is Derived    // true: instance is dynamically of type Derived
let check2 = instance is Base       // true: Derived inherits from Base
let check3 = instance is Unrelated  // false: Unrelated is not in the inheritance hierarchy
Protocol Conformance When Type is a protocol, the operator inspects the runtime type metadata of the instance. It evaluates to true if the underlying dynamic type conforms to the specified protocol. This metadata inspection occurs directly via the instance’s pointer for statically typed class instances, or via the existential container if the value is type-erased.
protocol Evaluable {}
class Node: Evaluable {}

let item: Any = Node()
let staticItem: Node = Node()

let conforms1 = item is Evaluable       // true: dynamic type conforms to Evaluable
let conforms2 = staticItem is Evaluable // true: evaluates class metadata directly
Optional Unwrapping The is operator automatically looks through Optional wrappers when evaluating types. If an expression is an Optional containing a value, evaluating it against the underlying wrapped type (or any type the wrapped value is compatible with) returns true. This implicit unwrapping is a fundamental mechanic of dynamic type checking in Swift.
let optionalValue: Int? = 5
let anyOptional: Any = optionalValue

let check1 = optionalValue is Int // true: implicitly unwraps the Optional
let check2 = anyOptional is Int   // true: looks through both Any and Optional wrappers
Metatype Checking The is operator can evaluate metatypes (the type of a type) by checking if a given type object matches a specific .Type or .Protocol.
let typeInstance: Any.Type = Derived.self

let isDerivedType = typeInstance is Derived.Type // true
let isBaseType = typeInstance is Base.Type       // true: Derived.Type is a subtype of Base.Type

Compiler Behavior and Optimization

While the is operator is designed for runtime evaluation, the Swift compiler performs static analysis during compilation.
  • Trivially True/False: If the compiler can statically prove that the expression will always be of Type (or will never be of Type), it will emit a warning (e.g., “‘is’ test is always true”) and optimize the instruction by replacing the runtime check with a constant true or false literal.
  • Value Types: Because structs and enums do not support inheritance, using is to check a concrete value type against another concrete value type is statically resolved as false by the compiler. For value types, is is mechanically relevant only when the expression is an existential type (such as Any or a protocol type) masking the underlying concrete type.
Master Swift with Deep Grasping Methodology!Learn More