Typealias — co to jest, składnia i zastosowanie w Kotlin

Autor: IT Sectr Opublikowano: 2026-06-23 Czas czytania: 7 min

Typealias to mechanizm Kotlin do tworzenia alternatywnej nazwy istniejącego typu. Słowo kluczowe typealias pozwala zastąpić złożoną deklarację typu krótkim i zrozumiałym aliasem, nie tworząc nowego typu. Według dokumentacji Kotlin (2026), typealias zwiększa czytelność kodu, szczególnie w sygnaturach funkcji z typami funkcyjnymi. Typealias sprawia, że kod staje się samodokumentujący, zastępując wielosłowne deklaracje zrozumiałymi nazwanymi typami.

Najważniejsze

  • Typealias — alias dla istniejącego typu, nie tworzący nowego typu
  • Typy funkcyjne — typealias zastępuje złożone (T) -> R czytelnymi nazwami, takimi jak Callback
  • Generyki — typealias obsługuje parametry uogólnione: typealias ListMapper = (T) -> T
  • Klasy zagnieżdżone — typealias skraca dostęp do klas zagnieżdżonych z innych pakietów
  • Bezpieczeństwo typów — typealias nie dodaje kontroli na etapie kompilacji, alias jest w pełni wymienny z oryginałem

Co to jest typealias?

Typealias (alias typu) — to deklaracja wprowadzająca alternatywną nazwę dla istniejącego typu. Składnia: typealias NowaNazwa = IstniejącyTyp. Po deklaracji NowaNazwa może być używana wszędzie tam, gdzie oczekiwany jest IstniejącyTyp — kompilator traktuje je jako jeden i ten sam typ. Na poziomie kodu bajtowego typealias nie pozostawia śladów: wszystkie informacje o aliasie są usuwane na etapie kompilacji.

Głównym celem typealias jest poprawa czytelności kodu. Zamiast wielosłownej sygnatury fun process(callback: (Result) -> Unit) można napisać typealias Callback = (Result) -> Unit i używać Callback jako typu parametru. Jest to szczególnie przydatne, gdy ten sam typ funkcyjny powtarza się w wielu miejscach kodu: alias służy jako pojedynczy punkt definicji i dokumentuje przeznaczenie typu.

Typealias nie tworzy nowego typu — to tylko synonim. Zmienne typu Callback i (Result) -> Unit są w pełni wymienne. Kompilator nie zgłosi błędu, jeśli do funkcji oczekującej Callback zostanie przekazana lambda bezpośrednio. To odróżnia typealias od inline class (value class), która tworzy nowy typ-opakowujący z kontrolą na etapie kompilacji. Typealias to zmiana nazwy, a nie opakowanie.

Typealias dla typów funkcyjnych

Najczęstszym scenariuszem użycia typealias w Kotlin są typy funkcyjne. Długie sygnatury takie jak (Int, String) -> Boolean czy (List) -> Result utrudniają czytanie kodu. Typealias zamienia je w krótkie znaczące nazwy, które dokumentują przeznaczenie funkcji: typealias Validator = (String) -> Boolean określa, że jest to walidator ciągu znaków.

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

W przykładzie typealias UserFilter ukrywa złożony typ funkcyjny (List) -> List za krótką nazwą. Sygnatura findUsers staje się czytelna: «przyjmuje UserFilter, zwraca List». Typealias OnClickListener sprawia, że kod przypomina deklarację interfejsu, ale bez narzutu na tworzenie osobnego interfejsu lub klasy abstrakcyjnej. Lambdy i funkcje anonimowe działają jak zwykle — typealias nie wymaga zmian w kodzie wywołującym.

Typealias z generykami

Typealias obsługuje parametry uogólnione (generyki), co czyni go jeszcze bardziej elastycznym. Można zdefiniować typealias Mapper = (T) -> R i używać z dowolnymi typami. Kompilator podstawia konkretne typy w miejsce parametrów przy każdym użyciu aliasu, zachowując pełne bezpieczeństwo typów.

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

W listingu Mapper — to uogólniony alias dla dowolnego przekształcenia z T na R. Provider — dostawca wartości (fabryka bez argumentów). ListTransformer — funkcja przekształcająca listę. Przy wywołaniu processNumbers(mapper: Mapper) kompilator rozwija alias do (Int) -> String. Generyki czynią typealias uniwersalnym narzędziem, odpowiednim dla każdego kontekstu bez powielania deklaracji.

Typealias dla klas zagnieżdżonych i długich nazw

Klasy zagnieżdżone i długie sparametryzowane typy — to kolejny obszar, w którym typealias znacząco upraszcza kod. Jeśli klasa znajduje się głęboko w hierarchii zagnieżdżenia (Outer.Inner.Nested), odwołanie do niej przez pełną nazwę zaśmieca kod. Typealias skraca taki dostęp i czyni go bardziej czytelnym. Jest to szczególnie istotne w przypadku klas z bibliotek zewnętrznych o długich nazwach.

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
}

W przykładzie NetworkError — to alias dla zagnieżdżonej klasy NetworkResponse.Error. Przy imporcie typealias można używać NetworkError jako zwykłego typu, nie ujawniając hierarchii zagnieżdżenia. JsonMap dokumentuje, że mapa reprezentuje obiekt JSON. UserId wyjaśnia przeznaczenie Long w konkretnym kontekście — czytelnik od razu rozumie, że to identyfikator użytkownika, a nie dowolna liczba. Typealias nie chroni jednak przed przekazaniem zwykłego Long tam, gdzie oczekiwane jest UserId — do tego potrzebny jest value class.

Typealias vs inline class: różnice

Typealias i inline class (value class) rozwiązują różne zadania, choć oba wprowadzają nową nazwę dla typu. Typealias to tylko synonim: zmienna typu UserId = Long przyjmuje dowolny Long bez kontroli. Inline class opakowuje wartość w nowy typ, który jest sprawdzany na etapie kompilacji: przekazanie zwykłego Long tam, gdzie oczekiwany jest inline class UserId, jest niemożliwe bez jawnej konwersji.

CechaTypealiasInline class
Nowy typNie — synonim oryginałuTak — nowy typ z kontrolą
WydajnośćZerowa — usuwany całkowicieZerowa — opakowanie usuwane w kodzie bajtowym
DziedziczenieNieNie (final class)
Własne metodyNieTak — można deklarować funkcje
Bezpieczeństwo typówNie — wymienny z oryginałemTak — kompilator rozróżnia typy

Tabela pokazuje różnicę między tymi dwoma mechanizmami. Typealias nadaje się do krótkich nazw i dokumentacji kodu, gdy nie jest wymagana ścisła typizacja. Inline class przez słowo kluczowe value class (wcześniej inline class) jest potrzebny, gdy ważne jest rozróżnianie semantycznie różnych wartości tego samego typu prymitywnego. Na przykład UserId i OrderId oba są Long, ale przekazanie jednego tam, gdzie oczekiwany jest drugi, to błąd logiczny, który value class zapobiega na etapie kompilacji.

Często zadawane pytania

Czym typealias różni się od import alias?

Import alias (import com.example.LongName as Short) działa na poziomie importu — skraca nazwę tylko w bieżącym pliku. Typealias deklaruje globalny alias dostępny w całym projekcie po imporcie.

Czy można użyć typealias do tworzenia rekurencyjnego typu?

Tak, typealias obsługuje rekurencyjne definicje dla typów funkcyjnych, ale z ostrożnością: typealias Rec = (T) -> Rec działa, ale rekurencyjne odniesienia do object — nie. Kompilator sprawdza cykle i zgłasza błąd dla nieskończonych definicji.

Czy typealias wpływa na wydajność?

Nie, typealias jest całkowicie usuwany na etapie kompilacji. W kodzie bajtowym i w runtime używany jest oryginalny typ bez żadnego opakowania. Wydajność jest identyczna z bezpośrednim użyciem oryginalnego typu.

Jaki jest maksymalny poziom zagnieżdżenia dla typealias?

Typealias może odnosić się do innego typealias — nazywa się to łańcuchem aliasów. Głębokość łańcucha formalnie nie jest ograniczona, ale dla czytelności zaleca się nie więcej niż 2–3 poziomy. Kompilator rozwija łańcuch całkowicie na etapie analizy.

Czy można zadeklarować typealias wewnątrz funkcji?

Nie, typealias to deklaracja poziomu najwyższego lub element klasy/obiektu. Wewnątrz funkcji nie można zadeklarować typealias. Do lokalnego skracania typów używaj import alias wewnątrz pliku lub wynieś typealias na poziom modułu.

Podsumowanie

  • Typealias — synonim dla istniejącego typu, nie tworzący nowego typu i usuwany na etapie kompilacji
  • Typy funkcyjne — główny obszar zastosowania: typealias zastępuje (T) -> R czytelną nazwą, taką jak Callback
  • Generyki w typealias pozwalają tworzyć uogólnione aliasy Mapper dla dowolnych typów
  • Klasy zagnieżdżone — typealias skraca dostęp do głęboko zagnieżdżonych typów i długich nazw z bibliotek
  • Bezpieczeństwo typów jest nieobecne: typealias jest w pełni wymienny z oryginalnym typem
  • Value class — alternatywa dla typealias, gdy potrzebna jest ścisła kontrola typów z zerowym kosztem w runtime
  • Czytelność — główna zaleta: znaczące nazwy typów czynią kod samodokumentującym bez narzutu

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również