skip to content

What is a function-type alias in Kotlin, and how would you declare an alias named Handler for a function that takes an Event and returns Unit?

level: juniorimportance: must knowfreq 55%

answer

  1. typealias = nickname, not a new type
  2. (Event) -> Unit is the function type
  3. top-level only, no runtime object
  4. compiler expands alias back to the real type
  5. interchangeable with the raw arrow type

basics

~10 s

It gives a short, readable name to a function type. You write typealias Handler = (Event) -> Unit. Then you can use Handler anywhere instead of writing the long (Event) -> Unit signature.

solid answer

~40 s

A function-type alias uses the `typealias` keyword to name a function type so the long lambda signature reads clearly at use sites. Declaration: `typealias Handler = (Event) -> Unit`. After that, parameters, properties and return types can be typed as `Handler` instead of `(Event) -> Unit`. It is purely a compile-time, top-level naming convenience: the compiler expands `Handler` back to `(Event) -> Unit`, so a `Handler` and a raw `(Event) -> Unit` are the same type and interchangeable, with no runtime object or wrapper created. Aliases must be declared at file/top level (not inside a function or class body). They are great for callback signatures, comparators, and event handlers where the bare arrow syntax would otherwise repeat and obscure intent.

code

kotlin · 11 lines
kotlin
typealias Handler = (Event) -> Unit

class EventBus {
    private val handlers = mutableListOf<Handler>()
    fun subscribe(handler: Handler) { handlers += handler }
    fun publish(event: Event) { handlers.forEach { it(event) } }
}

// A raw (Event) -> Unit is accepted because it IS the same type:
val raw: (Event) -> Unit = { e -> println(e) }
EventBus().subscribe(raw)

go deeper

for a junior

Can write typealias Handler = (Event) -> Unit and use it as a parameter type.

for a middle

Knows it is a compile-time alias interchangeable with the raw function type and has no runtime cost.

for a senior

Explains the no-extra-type-safety consequence and contrasts with fun interface / value class for nominal types.

for a principal

Frames aliases as API-readability tooling and decides when nominal typing (real type) is warranted over an alias in a public contract.

## What a function-type alias is A **type alias** is an alternative name for an existing type, introduced with the `typealias` keyword. A **function-type alias** specifically names a *function type* — a type written with the arrow syntax `(Params) -> ReturnType`. Kotlin function types look like `(Event) -> Unit`, `(Int, Int) -> Int`, or `suspend () -> String`. When these signatures appear repeatedly (callbacks, listeners, comparators) they become noisy. A typealias gives them a domain name: ```kotlin typealias Handler = (Event) -> Unit fun register(onEvent: Handler) { /* ... */ } val h: Handler = { event -> println(event) } register(h) register { event -> println(event) } // lambda literal works too ``` ## Key properties - **`typealias` is top-level only.** It must be declared at file scope (or inside an object/companion as a member in newer versions), *never* inside a function body. - **It is a pure compile-time alias, not a new type.** The compiler erases `Handler` to `(Event) -> Unit`. So `Handler` and `(Event) -> Unit` are the *same* type; you can pass one where the other is expected with no conversion. This is unlike an `inline value class` wrapper, which *is* a distinct type. - **No runtime cost / no wrapper object.** Nothing is allocated; there is no `Handler` class in the bytecode. - **Receiver and suspend forms are supported.** You can alias `typealias Click = View.() -> Unit` (function type *with receiver*) or `typealias AsyncOp = suspend () -> Result`. ## Why use them - Readability at call sites and in public APIs. - A single place to change a callback signature. - Self-documenting names (`Validator`, `Reducer`, `Comparator`-like types). ## Limitations Because it is not a real type, a function-type alias gives **no extra type safety** — you cannot distinguish two aliases of the *same* underlying function type, and you cannot overload solely by alias name. For nominal distinctness you need a real class or a functional interface (`fun interface`).

  • Can you declare a typealias inside a function body?
    No. Type aliases must be declared at the top (file/class) level; declaring one inside a function is a compile error.
  • Does Handler create a new runtime type you can check with `is Handler`?
    No. It expands to `(Event) -> Unit` at compile time, so `is Handler` is just `is Function1<Event, Unit>`; there is no distinct Handler class.

Like a contact nickname in your phone: 'Mom' and the real phone number are the same number, just easier to read.

saying these in an interview costs you the question

  • Saying typealias creates a brand-new distinct type with its own runtime class
  • Claiming it adds type safety so two aliases of the same type can't be mixed
  • Thinking a typealias allocates a wrapper object at runtime
  • Trying to declare the alias inside a method body
  • Confusing typealias with a `fun interface` or `value class`

context