Tipe yang panjang seperti Map<String, List<Pair<Int, String>>> sulit dibaca dan mudah salah ketik. Kotlin menyediakan typealias — mekanisme memberi nama alternatif untuk tipe yang sudah ada. Alias tidak membuat tipe baru; alias hanya memberi nama lain yang dipertukarkan dengan tipe aslinya. Pada chapter ini kita akan membedah deklarasi typealias, alias untuk tipe generik dan function type, serta kapan memakainya.
Sintaks typealias #
Deklarasi typealias berada di top-level (di luar function/class). Sintaksnya:
typealias NamaAlias = TipeAsliSetelah deklarasi, NamaAlias dapat dipakai sebagai pengganti TipeAsli di seluruh kode. Kedua nama saling dipertukarkan — kompilator memperlakukan keduanya sebagai tipe yang sama.
Contoh typealias umum #
Berikut beberapa alias yang sering dipakai di proyek Kotlin:
typealias Strings = List<String>
typealias IntMap = Map<Int, String>
typealias DaftarPengguna = List<String>
typealias PasanganKunciNilai<K, V> = Pair<K, V>
typealias Predikat<T> = (T) -> Boolean
typealias ID = UInt
typealias Token = StringAlias juga memperbolehkan parameter generik. PasanganKunciNilai<K, V> di atas menerima dua parameter generik sehingga dapat digunakan sebagai PasanganKunciNilai<String, Int>.
Demonstrasi typealias #
Berikut program lengkap yang memperlihatkan penerapan typealias:
typealias DaftarPengguna = List<String>
typealias PasanganKunciNilai<K, V> = Pair<K, V>
typealias Predikat<T> = (T) -> Boolean
typealias ID = UInt
typealias Token = String
data class Pengguna(val id: ID, val nama: String, val aktif: Boolean)
fun filterPengguna(pengguna: DaftarPengguna, kondisi: Predikat<String>): DaftarPengguna {
return pengguna.filter(kondisi)
}
fun main() {
val idBudi: ID = 1u
val token: Token = "abc123"
println("ID Budi = $idBudi")
println("Token = $token")
println()
val pengguna: DaftarPengguna = listOf("Budi", "Siti", "Dewi", "Andi")
println("Semua pengguna: $pengguna")
val penggunaDenganB: Predikat<String> = { nama -> nama.startsWith("B") }
val hasilFilter = filterPengguna(pengguna, penggunaDenganB)
println("Pengguna berawalan B: $hasilFilter")
println()
val pasangan: PasanganKunciNilai<String, Int> = "umur" to 25
println("Pasangan: $pasangan")
println()
val daftarKunci: MutableList<PasanganKunciNilai<String, Int>> = mutableListOf()
daftarKunci.add("umur" to 25)
daftarKunci.add("berat" to 65)
daftarKunci.add("tinggi" to 170)
println("Daftar pasangan:")
for ((kunci, nilai) in daftarKunci) {
println(" $kunci = $nilai")
}
println()
val data = Pengguna(2u, "Siti", true)
println("Pengguna: $data")
println("Tipe data.id = ${data.id::class.simpleName}")
println("Tipe data = ${data::class.simpleName}")
}Output yang Dihasilkan:
ID Budi = 1
Token = abc123
Semua pengguna: [Budi, Siti, Dewi, Andi]
Pengguna berawalan B: [Budi]
Pasangan: (umur, 25)
Daftar pasangan:
umur = 25
berat = 65
tinggi = 170
Pengguna: Pengguna(id=2, nama=Siti, aktif=true)
Tipe data.id = UInt
Tipe data = PenggunaMari kita amati baris-baris penting pada kode di atas:
- Baris 1-5 — deklarasi alias di top-level. Alias
DaftarPenggunamenggantikanList<String>; aliasPredikat<T>menggantikan function type(T) -> Boolean. - Baris 7 (
data class Pengguna(val id: ID, ...)) — aliasID = UIntdipakai sebagai tipe propertyid. Kode membaca niat bahwaidadalah identifier unsigned. - Baris 9-11 (
fun filterPengguna(pengguna: DaftarPengguna, kondisi: Predikat<String>)) — signature function lebih ringkas dan ekspresif dibanding versi tanpa alias (fun filterPengguna(pengguna: List<String>, kondisi: (String) -> Boolean)). - Baris 14 (
val idBudi: ID = 1u) —1uadalah literal unsigned; tipe eksplisitID(aliasUInt) membuat kode jelas. - Baris 20 (
val penggunaDenganB: Predikat<String> = { nama -> ... }) — alias function type membuat deklarasi lambda lebih jelas. Tanpa alias, tipe ini akan tertulis(String) -> Boolean. - Baris 26 (
val pasangan: PasanganKunciNilai<String, Int>) — alias generik dengan parameter tipe.Pair<String, Int>lebih singkat ditulis sebagai alias. - Baris 30 (
val daftarKunci: MutableList<PasanganKunciNilai<String, Int>>) — alias menghindari penulisan berulangMutableList<Pair<String, Int>>. Tanpa alias, pan signature ini akan sangat panjang. - Baris 38-40 (
data.id::class.simpleName) — meskipunidbertipeID(alias),::class.simpleNamemengembalikan nama class sebenarnya, yaituUInt. Hal ini membuktikan bahwa alias hanya nama lain — representasi runtime tetap sama.
Type alias vs subclass #
Penting dipahami bahwa typealias tidak membuat tipe baru. Alias dan tipe asli saling dipertukarkan sepenuhnya:
typealias Tokens = List<String>
val a: List<String> = listOf("x", "y")
val b: Tokens = a // sah
val c: List<String> = b // sah jugaBerbeda dari data class yang membuat tipe baru, alias hanya memberi label. Hal ini berimplikasi:
- Method overload berdasarkan alias tidak mungkin (karena tipe sama).
- Pengecekan
istetap berdasarkan tipe asli. - Tidak ada overhead runtime.
Type alias untuk function type #
Alias paling berguna untuk function type yang panjang:
typealias Mapper<T, U> = (T) -> U
typealias Predikat<T> = (T) -> Boolean
typealias Aksi = () -> Unit
typealias Handler<T> = (T, Throwable?) -> Unit
fun <T> terapkan(data: T, mapper: Mapper<T, String>): String = mapper(data)Tanpa alias, signature function yang menerima banyak function type akan sulit dibaca.
Kapan menggunakan typealias #
| Skenario | Gunakan typealias? |
|---|---|
| Tipe generik panjang dipakai berulang | Ya |
Function type kompleks ((T, Throwable) -> Unit) | Ya |
Memberi nama domain pada tipe primitif (ID = UInt) | Ya, untuk kejelasan |
| Membuat tipe baru yang distinct | Tidak — gunakan data class |
| Validasi constraint tipe | Tidak — gunakan inline class / value class |
Referensi Lanjutan #
- Properties — dokumentasi properti Kotlin sebagai konteks deklarasi tipe alias untuk properti dan fungsi
- Coding conventions
— panduan konvensi penulisan Kotlin termasuk penamaan
typealias
Alias adalah alat untuk menjaga keterbacaan tanpa menambah tipe baru. Berikutnya, kita akan melihat deklarasi konstanta compile-time melalui const val — pada chapter Konstanta dengan const val.