Typealias — що це, синтаксис і застосування в Kotlin

Автор: IT Sectr Опубліковано: 2026-06-23 Час читання: 7 хв

Typealias — це механізм Kotlin для створення альтернативної назви існуючого типу. Ключове слово typealias дозволяє замінити складне оголошення типу коротким і зрозумілим псевдонімом, не створюючи нового типу. Згідно з документацією Kotlin (2026), typealias підвищує читабельність коду, особливо в сигнатурах функцій із функціональними типами. Typealias робить код самодокументованим, замінюючи багатослівні оголошення зрозумілими іменованими типами.

Головне

  • Typealias — псевдонім для існуючого типу, що не створює нового типу
  • Функціональні типи — typealias замінює складні (T) -> R на читабельні назви на кшталт Callback
  • Дженерики — typealias підтримує узагальнені параметри: typealias ListMapper = (T) -> T
  • Вкладені класи — typealias скорочує доступ до вкладених класів з інших пакетів
  • Типобезпека — typealias не додає перевірок на етапі компіляції; псевдонім повністю взаємозамінний з оригіналом

Що таке typealias?

Typealias (псевдонім типу) — це декларація, що вводить альтернативне ім’я для існуючого типу. Синтаксис: typealias НовеІм’я = ІснуючийТип. Після оголошення НовеІм’я можна використовувати скрізь, де очікується ІснуючийТип — компілятор сприймає їх як один і той самий тип. На рівні байткоду typealias не залишає слідів: уся інформація про псевдонім стирається на етапі компіляції.

Головна мета typealias — покращення читабельності коду. Замість багатослівної сигнатури fun process(callback: (Result) -> Unit) можна написати typealias Callback = (Result) -> Unit і використовувати Callback як тип параметра. Це особливо корисно, коли один і той самий функціональний тип повторюється в кількох місцях коду: псевдонім слугує єдиною точкою визначення та документує призначення типу.

Typealias не створює новий тип — це просто синонім. Змінні типу Callback і (Result) -> Unit повністю взаємозамінні. Компілятор не видасть помилку, якщо в функцію, яка очікує Callback, передати лямбду безпосередньо. Це відрізняє typealias від inline class (value class), який створює новий тип-обгортку з перевіркою на етапі компіляції. Typealias — це перейменування, а не обгортка.

Typealias для функціональних типів

Найпоширеніший сценарій застосування typealias у Kotlin — функціональні типи. Довгі сигнатури на кшталт (Int, String) -> Boolean або (List) -> Result роблять код важким для читання. Typealias перетворює їх на короткі осмислені імена, які документують призначення функції: typealias Validator = (String) -> Boolean визначає, що це валідатор рядка.

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 = {}
}

У прикладі typealias UserFilter приховує складний функціональний тип (List) -> List за коротким іменем. Сигнатура findUsers стає читабельною: «приймає UserFilter, повертає List». Typealias OnClickListener робить код схожим на декларацію інтерфейсу, але без накладних витрат на створення окремого інтерфейсу чи абстрактного класу. При цьому лямбди та анонімні функції продовжують працювати як зазвичай — typealias не вимагає змін у викликаючому коді.

Typealias з дженериками

Typealias підтримує узагальнені параметри (дженерики), що робить його ще більш гнучким. Можна визначити typealias Mapper = (T) -> R і використовувати з будь-якими типами. Компілятор підставляє конкретні типи на місце параметрів при кожному використанні псевдоніма, зберігаючи повну типобезпеку.

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() }
}

У лістингу Mapper — узагальнений псевдонім для будь-якого перетворення з T у R. Provider — постачальник значення (фабрика без аргументів). ListTransformer — функція перетворення списку. При виклику processNumbers(mapper: Mapper) компілятор розкриває псевдонім у (Int) -> String. Дженерики роблять typealias універсальним інструментом, придатним для будь-яких контекстів без дублювання оголошень.

Typealias для вкладених і довгих імен

Вкладені класи та довгі параметризовані типи — ще одна сфера, де typealias суттєво спрощує код. Якщо клас знаходиться глибоко в ієрархії вкладеності (Outer.Inner.Nested), звернення до нього через повне ім’я захаращує код. Typealias скорочує такий доступ і робить його більш читабельним. Особливо це актуально для класів зі сторонніх бібліотек із довгими іменами.

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
}

У прикладі NetworkError — псевдонім для вкладеного класу NetworkResponse.Error. При імпорті typealias можна використовувати NetworkError як звичайний тип, не розкриваючи ієрархію вкладеності. JsonMap документує, що карта представляє JSON-об’єкт. UserId пояснює призначення Long у конкретному контексті — читач одразу розуміє, що це ідентифікатор користувача, а не довільне число. Однак typealias не захищає від передачі звичайного Long туди, де очікується UserId — для цього потрібен value class.

Typealias vs Inline Class: відмінності

Typealias і inline class (value class) вирішують різні завдання, хоча обидва вводять нове ім’я для типу. Typealias — це просто синонім: змінна типу UserId = Long приймає будь-який Long без перевірки. Inline class обгортає значення в новий тип, який перевіряється на етапі компіляції: передати звичайний Long туди, де очікується inline class UserId, неможливо без явного перетворення.

ХарактеристикаTypealiasInline class
Новий типНі — синонім оригіналуТак — новий тип з перевірками
ПродуктивністьНульова — стирається в нульНульова — обгортка видаляється в байткоді
СпадкуванняНіНі (final class)
Власні методиНіТак — можна оголошувати функції
ТипобезпекаНі — взаємозамінний з оригіналомТак — компілятор розрізняє типи

У таблиці показано різницю між двома механізмами. Typealias підходить для коротких імен і документації коду, коли не потрібна строга типізація. Inline class через ключове слово value class (раніше inline class) потрібен, коли важливо розрізняти семантично різні значення одного й того самого примітивного типу. Наприклад, UserId і OrderId обидва є Long, але передача одного туди, де очікується інший — логічна помилка, яку value class запобігає на етапі компіляції.

Часті запитання

Чим typealias відрізняється від import alias?

Import alias (import com.example.LongName as Short) працює на рівні імпорту — скорочує ім’я лише в поточному файлі. Typealias оголошує глобальний псевдонім, доступний у всьому проекті після імпорту.

Чи можна використовувати typealias для створення рекурсивного типу?

Так, typealias підтримує рекурсивні визначення для функціональних типів, але з обережністю: typealias Rec = (T) -> Rec працює, а рекурсивні посилання на object — ні. Компілятор перевіряє цикли й видає помилку для нескінченних визначень.

Чи впливає typealias на продуктивність?

Ні, typealias повністю стирається на етапі компіляції. У байткоді та runtime використовується оригінальний тип без жодної обгортки. Продуктивність ідентична використанню вихідного типу безпосередньо.

Який максимальний рівень вкладеності для typealias?

Typealias може посилатися на інший typealias — це називається ланцюжком псевдонімів. Глибина ланцюжка формально не обмежена, але для читабельності рекомендується не більше 2–3 рівнів. Компілятор розкриває ланцюжок повністю на етапі аналізу.

Чи можна оголосити typealias всередині функції?

Ні, typealias — декларація верхнього рівня або член класу/об’єкта. Всередині функцій typealias оголосити не можна. Для локального скорочення типів використовуйте import alias у файлі або виносьте typealias на рівень модуля.

Підсумки

  • Typealias — синонім для існуючого типу, що не створює нового типу й стирається на етапі компіляції
  • Функціональні типи — основна сфера застосування: typealias замінює (T) -> R на читабельне ім’я на кшталт Callback
  • Дженерики в typealias дозволяють створювати узагальнені псевдоніми Mapper для будь-яких типів
  • Вкладені класи — typealias скорочує доступ до глибоко вкладених типів і довгих імен з бібліотек
  • Типобезпека відсутня: typealias повністю взаємозамінний з оригінальним типом
  • Value class — альтернатива typealias, коли потрібна строга перевірка типів із нульовою вартістю в runtime
  • Читабельність — головна перевага: осмислені імена типів роблять код самодокументованим без оверхеду

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також