What is a top-level typealias in Kotlin, what can it and can't it do, and where must it be declared?
answer
- Alias for an existing type, not a new type
- Compile-time substitution, zero runtime cost
- Top-level only - never inside class or function
- No extra type safety; use value class for that
- Can be generic: typealias Predicate<T>
basics
~20 sA typealias gives an existing type a shorter or clearer name. It creates no new type - it is just an alias. In Kotlin it must be declared at the top level of a file, not inside a function or class body.
solid answer
~40 sA typealias introduces an alternative name for an existing type: typealias Handler = (Event) -> Unit. It is a pure compile-time substitution - it does not create a new type, so Handler and (Event) -> Unit are fully interchangeable and assignment-compatible; no wrapping, no runtime cost, and is/as checks see through it. It can name function types, generic instantiations (typealias StringMap = Map<String, String>), and can itself be generic (typealias Predicate<T> = (T) -> Boolean). Crucially, type aliases may only be declared at the top level of a file - they cannot be nested in classes or functions. Because they erase to the underlying type, they provide no extra type safety; for distinct types use a value class (inline class) instead. Visibility modifiers (public/internal/private) apply.
code
kotlin · 7 linestypealias Callback<T> = (Result<T>) -> Unit
fun fetch(cb: Callback<String>) = cb(Result.success("ok"))
// Callback<String> IS (Result<String>) -> Unit - interchangeable
val c: (Result<String>) -> Unit = { }
fun use() = fetch(c) // compiles: same typego deeper
Knows typealias is a shorter name for an existing type and lives at the top level.
Explains it is compile-time substitution with no new type and can be generic over function/collection types.
Contrasts typealias (no safety, zero cost) with value class (distinct type) and applies the top-level-only restriction correctly.
Guides when aliases improve API readability vs. when domain types (value classes) are warranted, considering interop and refactor safety.
## What a typealias is `typealias` defines a second name for an existing type. Syntax: ```kotlin typealias Handler = (Event) -> Unit typealias StringMap = Map<String, String> typealias Predicate<T> = (T) -> Boolean // generic alias ``` It is resolved entirely at **compile time** by substitution. `Handler` and `(Event) -> Unit` are the *same* type to the compiler. ## What it does NOT do - It does **not** create a new, distinct type. There is **no** added type safety: a `typealias UserId = Int` is still just an `Int`, so you can pass any `Int` where a `UserId` is expected. - It adds **no runtime representation** - no wrapper object, no overhead. Reflection and `is`/`as` see the underlying type. ## Where it can be declared - top level only Type aliases must be **top-level** declarations in a file. You **cannot** declare a `typealias` inside a function body, and you cannot nest it as a member inside a class or interface. This is a deliberate language restriction. ```kotlin class Foo { // typealias Bar = Int // ERROR: nested type aliases are not allowed } fun work() { // typealias Local = Int // ERROR: not allowed inside a function } ``` ## Common uses - Shorten verbose generic/function types: `typealias ClickListener = (View, Int) -> Unit`. - Give domain meaning to a structure: `typealias Coordinates = Pair<Double, Double>`. ## typealias vs value class If you want a **distinct** type that prevents mixing `UserId` with a raw `Int`, use a `value class` (formerly inline class): ```kotlin @JvmInline value class UserId(val raw: Int) ``` Unlike a typealias, a `value class` is a real, type-safe type (with near-zero overhead via inlining where possible). ## Visibility A top-level `typealias` honors `public` (default), `internal`, and `private` (file-scoped) just like other top-level declarations.
- Does typealias UserId = Int stop you passing a plain Int where a UserId is expected?No. It is the same type, so any Int is accepted. Use a value class for that safety.
- Can you declare a typealias inside a class body?No. Type aliases are top-level only; nesting them in a class or function is a compile error.
A typealias is a nickname: calling Robert 'Bob' doesn't create a second person - both names point to exactly the same individual.
saying these in an interview costs you the question
- Claiming typealias creates a new distinct type
- Saying it adds type safety like a wrapper
- Thinking it has runtime overhead or boxing
- Believing you can declare it inside a function or class
- Confusing typealias with import-as renaming semantics