Typealias — это механизм Kotlin для создания альтернативного имени существующего типа. Ключевое слово typealias позволяет заменить сложное объявление типа коротким и понятным псевдонимом, не создавая нового типа. По данным документации Kotlin (2026), 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 в Kotlin — функциональные типы. Длинные сигнатуры вроде (Int, String) -> Boolean или (List
// 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
Typealias поддерживает обобщённые параметры (дженерики), что делает его ещё более гибким. Можно определить typealias Mapper
// 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
Вложенные классы и длинные параметризованные типы — ещё одна область, где typealias существенно упрощает код. Если класс находится глубоко в иерархии вложенности (Outer.Inner.Nested), обращение к нему через полное имя загромождает код. Typealias сокращает такой доступ и делает его более читаемым. Особенно это актуально для классов из сторонних библиотек с длинными именами.
// 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 и inline class (value class) решают разные задачи, хотя оба вводят новое имя для типа. Typealias — это просто синоним: переменная типа UserId = Long принимает любой Long без проверки. Inline class оборачивает значение в новый тип, который проверяется на этапе компиляции: передать обычный Long туда, где ожидается inline class UserId, невозможно без явного преобразования.
| Характеристика | Typealias | Inline class |
|---|---|---|
| Новый тип | Нет — синоним оригинала | Да — новый тип с проверками |
| Производительность | Нулевая — стирается в ноль | Нулевая — обёртка удаляется в байткоде |
| Наследование | Нет | Нет (final class) |
| Собственные методы | Нет | Да — можно объявлять функции |
| Типобезопасность | Нет — взаимозаменяем с оригиналом | Да — компилятор различает типы |
В таблице показана разница между двумя механизмами. Typealias подходит для кратких имён и документации кода, когда не требуется строгая типизация. Inline class через ключевое слово value class (ранее inline class) нужен, когда важно различать семантически разные значения одного и того же примитивного типа. Например, UserId и OrderId оба являются Long, но передача одного туда, где ожидается другой — логическая ошибка, которую value class предотвращает на этапе компиляции.
Часто задаваемые вопросы
Import alias (import com.example.LongName as Short) работает на уровне импорта — сокращает имя только в текущем файле. Typealias объявляет глобальный псевдоним, доступный во всём проекте после импорта.
Да, typealias поддерживает рекурсивные определения для функциональных типов, но с осторожностью: typealias Rec
Нет, typealias полностью стирается на этапе компиляции. В байткоде и runtime используется оригинальный тип без какой-либо обёртки. Производительность идентична использованию исходного типа напрямую.
Typealias может ссылаться на другой typealias — это называется цепочкой псевдонимов. Глубина цепочки формально не ограничена, но для читаемости рекомендуется не более 2–3 уровней. Компилятор раскрывает цепочку полностью на этапе анализа.
Нет, typealias — декларация верхнего уровня или член класса/объекта. Внутри функций typealias объявить нельзя. Для локального сокращения типов используйте import alias внутри файла или выносите typealias на уровень модуля.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также