Type Inference

In our previous posts, we learned about var (for variables that can change) and let (for constants that remain fixed). But did you notice that we didn’t always specify a data type when declaring variables and constants?

For example, when we wrote:

var name = "Alice"
let age = 25

we didn’t tell Swift that name is a string and age is an integer. Swift figured it out on its own.

This happens because of Type Inference — a feature that allows Swift to automatically determine the type of a variable or constant based on the assigned value.

In this post, we’ll learn what Type Inference is, why it’s useful, and how it works with var and let in Swift.

What is Type Inference?

Type Inference is Swift’s ability to automatically determine the type of a variable or constant based on its initial value. This means we don’t always have to explicitly state the type when declaring a variable or constant. Instead, Swift automatically determines the type based on what we assign.

For example:

var city = "Paris"

Here, Swift understands that city is a string because we assigned a string “Paris” to it.

Similarly:

let temperature = 30

Swift recognizes that temperature is an integer because the assigned value is 30.

Why is Type Inference Useful?

Type inference makes our code cleaner and easier to read by eliminating the need to manually specify types. It also reduces errors by ensuring type safety, preventing accidental mixing of incompatible types. It also makes coding faster because we don’t have to specify types when declaring variables and constants.

Let’s look at some examples to see how Type Inference works in Swift.

Let’s start with a simple example to see how Swift infers types for variables and constants.

var message = "Hello, Swift!" // Inferred as String

let year = 2025 // Inferred as Int

Swift sees Hello, Swift! and infers that message is a string. Similarly, it sees 2025 and infers that year is an integer. We do not need to explicitly write:

var message: String = "Hello, Swift!"

let year: Int = 2025

Now let’s see another example about integer and double.

var price = 19.99 // Inferred as Double

let count = 5 // Inferred as Int

Since we assigned a decimal value to price, it is inferred as a double, while count is inferred as an integer because it has an integer value. However, there could be situations where we want to explicitly declare the type. For example, if we wanted count to be a double, we can explicitly declare it as such:

var count: Double = 5.0 // Explicitly declared as Double

Similarly, if we want price to be treated as an integer instead of a Double, we can also explicitly declare it as an Int:

var price: Int = 19 // Explicitly declared as Int
Type Inference with Boolean Values

Now let’s create a boolean variable:

let isSunny = true

Swift sees true and infers that isSunny is a Bool.

If we try to assign something else to it, Swift won’t allow it:

isSunny = 1 // Error: Cannot assign Int to a Bool
Type Inference with Operations

Swift can infer types based on math operations:

var result = 10 + 5.5

Since 10 is an Int and 5.5 is a Double, Swift infers result as a Double, because Swift automatically converts integer to double in mixed operations.

Explicitly Specifying a Type

While Type Inference is helpful, sometimes you may need to specify a type. For example if we want a decimal value but without Swift assuming it’s a Double:

let pi: Float = 3.14159

Even though 3.14159 is normally inferred as a Double, we force it to be a Float instead. This can be useful for memory optimization, since Float takes up less space than Double.

Declaring an Empty Variable

If we declare a variable without assigning a value, Swift won’t know the type and therefore produces an error.

var name // Error: Type annotation missing

To fix this, we can assign a value to the variable right away:

var name = "Alice"

Or we can explicitly define the type:

var username: String

Key Takeaways

  • Type Inference lets Swift automatically determine the type of var and let values.
  • Swift decides type based on initial value (e.g., 3.14 → Double, “Hello” → String).
  • We can override inference by specifying a type explicitly.
  • If a variable is declared but not initialized, Swift requires a type annotation.