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
// Без typealias
fun findUsers(
filter: (List<User>) -> List<User>
): List<User>
// Са typealias
typealias UserFilter = (List<User>) -> List<User>
fun findUsers(filter: UserFilter): List<User>
// Употреба у класи
typealias OnClickListener = (View) -> Unit
class Button {
var onClick: OnClickListener = {}
}
У примеру, typealias UserFilter скрива сложени функцијски тип (List
Typealias подржава генеричке параметре, што га чини још флексибилнијим. Може се дефинисати typealias Mapper
// Генерички 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 тип је (Int) -> String
}
fun main() {
val config: Provider<String> = { "default config" }
val reverse: ListTransformer<Int> = { it.reversed() }
}
У листингу, Mapper
Угнежђене класе и дуги параметризовани типови — још једна област у којој typealias значајно поједностављује код. Ако се класа налази дубоко у хијерархији угнежђења (Outer.Inner.Nested), позивање на њу пуним именом загушује код. Typealias скраћује такав приступ и чини га читљивијим. Ово је посебно важно за класе из спољних библиотека са дугим именима.
// Псеудоним за угнежђену класу
class NetworkResponse {
class Error(val code: Int, val message: String)
}
typealias NetworkError = NetworkResponse.Error
// Псеудоним за дуг библиотечки тип
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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође