Metatypes in Swift

Why .self and .type matter

Steven Curtis
5 min readApr 3


Photo by Jake Hills on Unsplash

Before we start

Difficulty: Beginner | Easy | Normal | Challenging

Keywords and Terminology:

Metatypes: the type of any type


  • None


In Swift, you might have noticed that some code uses .self and some uses .type for various uses which can seem rather opaque to the beginner.

These are useful, and should not simply be ignored however!

A Simple example

You might have a rather forced example as follows:

struct Person{
var name: String
init(_ name: String) { = name

let tina = Person("Tina")

so tina is clearly an instance of Person.

We can see this with the following print statements:

print(tina.self) // Person(name: "Tina")
print(type(of: tina)) // Person

The overview

Each instance of Person can be represented by two things, the Type of the metatype.

Type: Person
Metatype: Person.Type

The Type here represents the type of an instance, but the Metatype represents the metatype, which is a type that describes another type. In other words, the metatype describes the structure and properties of the type (including methods and properties) but does not describe the actual values.

When a function needs a type

So if you are writing a function that accepts a type (i..e Person.Type) rather than an instance you can write Person.Type as the type of the parameter — and that parameter would be Person.self.

A common use of self is from the register function in tableview:

tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "MyTableViewCell")

where the register function itself asks for any class with the definition:

func register(_ cellClass: AnyClass?, forCellReuseIdentifier identifier: String)



Recommended from Medium


See more recommendations