skip to content

actual typealias

An actual typealias satisfies an expect class by pointing at an existing platform type, so you reuse the JDK or Apple type instead of wrapping it. It is the cheapest possible actual and the one to reach for first.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

In a Kotlin Multiplatform project, what does `actual typealias UUID = java.util.UUID` do, and why would you use it instead of writing an `actual class`?

level: juniorimportance: must knowfreq 55%

answer

  1. typealias = new name, not new type
  2. actual satisfies expect by pointing at JDK type
  3. no wrapper, no delegation, members free
  4. java.util.UUID is the class itself
  5. structural match required

basics

~10 s

It says: on this platform, the shared expect class UUID is exactly the platform's own UUID type. You reuse an existing native type directly instead of writing a wrapper class around it.

solid answer

~40 s

In common code you declare `expect class UUID`. Each platform must supply a matching `actual`. With `actual typealias UUID = java.util.UUID`, the JVM target satisfies the `expect` by pointing the name `UUID` at the already-existing `java.util.UUID`. No new class is generated and no wrapper/delegation is written — at compile time `UUID` simply *is* `java.util.UUID`, so all its constructors, methods (`randomUUID()`, `toString()`), and equality come for free. You use this when a perfectly good platform type already exists and writing an `actual class` would just mean re-declaring or delegating every member by hand. It is the idiomatic way to bridge shared API to JDK/native types like `UUID`, `BigDecimal`, or `AtomicInteger`.

code

kotlin · 11 lines
kotlin
// commonMain
expect class UUID {
    override fun toString(): String
    companion object { fun randomUUID(): UUID }
}

// jvmMain — satisfied with zero wrapper code
actual typealias UUID = java.util.UUID

// commonMain usage works on JVM thanks to the alias
fun newId(): UUID = UUID.randomUUID()

go deeper

for a junior

Knows expect/actual pair the contract with a per-platform implementation and that the alias reuses an existing type.

for a middle

Explains typealias creates no new type and members come for free, and contrasts with actual class.

for a senior

Discusses structural-match requirement, interop benefits, and when an alias is impossible (must wrap).

for a principal

Frames it as an API-design lever for binary/source compatibility and library boundary shaping across targets.

## The problem `expect`/`actual` solves Kotlin Multiplatform (KMP) lets you write **common** code shared across targets (JVM, Native, JS, Wasm). When common code needs something that only exists per-platform, you declare an **`expect`** declaration — a contract with no body — and each target provides a matching **`actual`** implementation. ```kotlin // commonMain expect class UUID { override fun toString(): String companion object { fun randomUUID(): UUID } } ``` ## Two ways to provide the `actual` 1. **`actual class`** — you write a real class (often wrapping/delegating to a platform type). 2. **`actual typealias`** — you alias the `expect` name to an **existing** platform type. ```kotlin // jvmMain actual typealias UUID = java.util.UUID ``` A **typealias** introduces an alternative *name* for an existing type; it creates **no new type**. So after this alias, in JVM code the name `UUID` and `java.util.UUID` are literally interchangeable — same class, same bytecode, same methods, same `equals`/`hashCode`. ## Why prefer the typealias - **Zero wrapper cost.** No boxing, no delegation, no re-implementing members. `java.util.UUID.randomUUID()` already exists, so the companion/members are satisfied automatically. - **Seamless interop.** Java libraries returning `java.util.UUID` plug straight into your common `UUID` API with no conversion. - **Less code to maintain.** An `actual class` forces you to redeclare every member; the alias inherits them. ## What the compiler checks The aliased type must structurally match the `expect`: every member the `expect` declares (methods, properties, constructors, companion members) must already exist on `java.util.UUID` with compatible signatures, else you get an *actualization* error. ## When you can't use it If no single platform type matches the `expect` surface, or you need extra behavior the platform type lacks, fall back to `actual class` (possibly wrapping the platform type).

  • Does `actual typealias` create a new class at runtime?
    No. A typealias is purely a compile-time name; at runtime there is only `java.util.UUID`. No extra class or object is generated.
  • What happens if `java.util.UUID` is missing a method the `expect` declares?
    Compilation fails with an actualization error: the aliased type must provide every member the `expect` declares with a compatible signature.

It's like a nickname: 'UUID' is just another name for the same person java.util.UUID — not a new person who imitates them.

saying these in an interview costs you the question

  • Saying the typealias generates a wrapper class
  • Claiming it copies methods into a new type
  • Thinking it converts/boxes values at runtime
  • Believing typealias creates a distinct, non-interchangeable type

context

open as a page

What rules must hold for an `actual typealias` to legally satisfy an `expect class`? Give the constraints the compiler enforces.

level: middleimportance: should knowfreq 40%

basics

~20 s

The aliased platform type must already have everything the expect class promises — same members with matching signatures, matching visibility, and a companion if the expect declares one. The alias just renames that existing type.

open as a page

When designing a shared `expect class`, how do you decide between satisfying it with an `actual typealias` versus an `actual class`? Walk through the trade-offs.

level: seniorimportance: should knowfreq 28%

basics

~20 s

Use actual typealias when a platform type already matches the contract exactly — it's free and gives perfect interop. Use actual class when you need to add, rename, normalize, or hide members, or no single platform type fits.

open as a page

Your common `expect class UUID` is satisfied on JVM by `actual typealias UUID = java.util.UUID`. What surprising consequences does this aliasing have for common code consumers and for other targets?

level: seniorimportance: should knowfreq 30%

basics

~20 s

On JVM, UUID literally is java.util.UUID, so its full Java API leaks into JVM-side code, and common code must still only use the members the expect declares. Other targets need their own actual, which may behave differently.

open as a page

A teammate writes `actual typealias Instant = java.time.Instant` to satisfy `expect class Instant`, and it fails to compile. Walk through the likely causes and how to diagnose them.

level: middleimportance: nice to knowfreq 22%

basics

~20 s

Usually the expect class declares a member (method, constructor, or companion factory) that java.time.Instant doesn't expose with a matching signature, or visibility/type parameters don't line up. The fix is to align the expect surface or use an actual class.

open as a page