Kotlin is a statically typed language, which means every variable and expression has a type known at compile time. However, the compiler is smart enough to automatically infer types in most cases — a feature known as type inference.
Type inference allows the compiler to deduce the type of a variable, function, or expression without requiring the programmer to declare it explicitly. This results in cleaner, shorter, and more readable code.
val name = "Kotlin" // Compiler infers String
var age = 25 // Compiler infers Int
val pi = 3.1416 // Compiler infers Double
Understanding type inference is easier when you know the difference between statically and dynamically typed languages.
Kotlin’s type inference lets you skip writing explicit types, but the language is still statically typed — the type is fixed at compile time.
val x = 10) → type inferred from literal (Int)val data = getUser()) → type inferred from return typefun add(a: Int, b: Int) = a + b // Return type inferred as Int
fun greeting() = "Hello, Kotlin!" // Return type inferred as String
Functions with multiple return paths or complex logic require explicit return type declaration.
fun check(value: Int): String {
return if (value > 0) "Positive" else "Non-positive"
}
val numbers = listOf(1, 2, 3) // List<Int>
val names = mutableListOf("A", "B") // MutableList<String>
val map = mapOf(1 to "One", 2 to "Two") // Map<Int, String>
val numbers = listOf(1, 2, 3, 4)
val doubled = numbers.map { it * 2 } // 'it' inferred as Int
fun main() {
val name = "Kotlin"
var version = 2.0
val active = true
val numbers = listOf(1, 2, 3)
val doubled = numbers.map { it * 2 }
println("Language: $name, Version: $version, Active: $active")
println("Doubled List: $doubled")
}
Output:
Language: Kotlin, Version: 2.0, Active: true
Doubled List: [2, 4, 6]