Typealias — What It Is, Syntax and Usage in Kotlin

Author: IT Sectr Published: 2026-06-23 Reading time: 7 min

Typealias is a Kotlin mechanism for creating an alternative name for an existing type. The typealias keyword allows you to replace a complex type declaration with a short and clear alias without creating a new type. According to the Kotlin documentation (2026), typealias improves code readability, especially in function signatures with functional types. Typealias makes code self-documenting by replacing verbose declarations with clear named types.

Key Takeaways

  • Typealias — an alias for an existing type that does not create a new type
  • Functional types — typealias replaces complex (T) -> R with readable names like Callback
  • Generics — typealias supports generic parameters: typealias ListMapper = (T) -> T
  • Nested classes — typealias shortens access to nested classes from other packages
  • Type safety — typealias does not add compile-time checks; the alias is fully interchangeable with the original

What is typealias?

Typealias (type alias) is a declaration that introduces an alternative name for an existing type. Syntax: typealias NewName = ExistingType. After declaration, NewName can be used wherever ExistingType is expected — the compiler treats them as the same type. At the bytecode level, typealias leaves no traces: all alias information is erased at compile time.

The main purpose of typealias is improving code readability. Instead of a verbose signature fun process(callback: (Result) -> Unit), you can write typealias Callback = (Result) -> Unit and use Callback as the parameter type. This is especially useful when the same functional type is repeated in several places in the code: the alias serves as a single point of definition and documents the type's purpose.

Typealias does not create a new type — it is just a synonym. Variables of type Callback and (Result) -> Unit are fully interchangeable. The compiler will not produce an error if a lambda is passed directly to a function expecting Callback. This distinguishes typealias from inline class (value class), which creates a new wrapper type with compile-time checking. Typealias is renaming, not wrapping.

Typealias for Functional Types

The most common use case for typealias in Kotlin is functional types. Long signatures like (Int, String) -> Boolean or (List) -> Result make code hard to read. Typealias turns them into short meaningful names that document the function's purpose: typealias Validator = (String) -> Boolean specifies that this is a string validator.

kotlin
// Without typealias
fun findUsers(
    filter: (List<User>) -> List<User>
): List<User>

// With typealias
typealias UserFilter = (List<User>) -> List<User>

fun findUsers(filter: UserFilter): List<User>

// Usage in class
typealias OnClickListener = (View) -> Unit

class Button {
    var onClick: OnClickListener = {}
}

In the example, the typealias UserFilter hides the complex functional type (List) -> List behind a short name. The findUsers signature becomes readable: "accepts UserFilter, returns List". The typealias OnClickListener makes the code resemble an interface declaration but without the overhead of creating a separate interface or abstract class. Meanwhile, lambdas and anonymous functions continue to work as usual — typealias requires no changes in the calling code.

Typealias with Generics

Typealias supports generic parameters, making it even more flexible. You can define typealias Mapper = (T) -> R and use it with any types. The compiler substitutes specific types for parameters with each use of the alias, preserving full type safety.

kotlin
// Generic typealias
typealias Mapper<T, R> = (T) -> R
typealias Provider<T> = () -> T
typealias ListTransformer<T> = (List<T>) -> List<T>

fun processNumbers(mapper: Mapper<Int, String>) {
    // mapper type is (Int) -> String
}

fun main() {
    val config: Provider<String> = { "default config" }
    val reverse: ListTransformer<Int> = { it.reversed() }
}

In the listing, Mapper is a generic alias for any transformation from T to R. Provider is a value supplier (a factory without arguments). ListTransformer is a list transformation function. When calling processNumbers(mapper: Mapper), the compiler expands the alias to (Int) -> String. Generics make typealias a universal tool suitable for any context without duplicating declarations.

Typealias for Nested and Long Names

Nested classes and long parameterized types are another area where typealias significantly simplifies code. If a class is deep in a nesting hierarchy (Outer.Inner.Nested), referencing it by its full name clutters the code. Typealias shortens such access and makes it more readable. This is especially relevant for classes from third-party libraries with long names.

kotlin
// Alias for nested class
class NetworkResponse {
    class Error(val code: Int, val message: String)
}
typealias NetworkError = NetworkResponse.Error

// Alias for long library type
typealias UserId = Long
typealias JsonMap = Map<String, Any?>

fun process(error: NetworkError) {
    println("${error.code}: ${error.message}")
}

fun parseJson(data: JsonMap): UserId {
    return data["id"] as? Long ?: 0L
}

In the example, NetworkError is an alias for the nested class NetworkResponse.Error. By importing the typealias, you can use NetworkError as a regular type without revealing the nesting hierarchy. JsonMap documents that the map represents a JSON object. UserId clarifies the purpose of Long in a specific context — the reader immediately understands that this is a user identifier, not an arbitrary number. However, typealias does not prevent passing a plain Long where UserId is expected — for that, a value class is needed.

Typealias vs Inline Class: Differences

Typealias and inline class (value class) solve different problems, although both introduce a new name for a type. Typealias is just a synonym: a variable of type UserId = Long accepts any Long without checking. Inline class wraps a value into a new type that is checked at compile time: passing a plain Long where an inline class UserId is expected is impossible without explicit conversion.

CharacteristicTypealiasInline class
New typeNo — synonym of the originalYes — new type with checks
PerformanceZero — erased completelyZero — wrapper removed in bytecode
InheritanceNoNo (final class)
Own methodsNoYes — functions can be declared
Type safetyNo — interchangeable with originalYes — compiler distinguishes types

The table shows the difference between the two mechanisms. Typealias is suitable for concise names and code documentation when strict typing is not required. Inline class via the value class keyword (formerly inline class) is needed when it is important to distinguish semantically different values of the same primitive type. For example, UserId and OrderId are both Long, but passing one where the other is expected is a logical error that value class prevents at compile time.

Frequently Asked Questions

How is typealias different from import alias?

Import alias (import com.example.LongName as Short) works at the import level — it shortens the name only in the current file. Typealias declares a global alias available throughout the project after import.

Can typealias be used to create a recursive type?

Yes, typealias supports recursive definitions for functional types, but with caution: typealias Rec = (T) -> Rec works, but recursive references to object do not. The compiler checks for cycles and produces an error for infinite definitions.

Does typealias affect performance?

No, typealias is completely erased at compile time. The original type is used at the bytecode and runtime level without any wrapper. Performance is identical to using the original type directly.

What is the maximum nesting level for typealias?

Typealias can reference another typealias — this is called a chain of aliases. The depth of the chain is formally unlimited, but for readability no more than 2–3 levels are recommended. The compiler fully resolves the chain at the analysis stage.

Can typealias be declared inside a function?

No, typealias is a top-level declaration or a member of a class/object. Typealias cannot be declared inside functions. For local type shortening, use import alias within the file or place the typealias at the module level.

Summary

  • Typealias — a synonym for an existing type that does not create a new type and is erased at compile time
  • Functional types — the main use case: typealias replaces (T) -> R with a readable name like Callback
  • Generics in typealias allow creating generic aliases Mapper for any types
  • Nested classes — typealias shortens access to deeply nested types and long names from libraries
  • Type safety is absent: typealias is fully interchangeable with the original type
  • Value class — an alternative to typealias when strict type checking with zero runtime cost is needed
  • Readability — the main advantage: meaningful type names make code self-documenting without overhead

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also