Type Aliases in Kotlin

In this blog, we will see how to use type alias and what is the benefit of it. We are going to learn about,

  • What are Type Aliases in Kotlin?
  • How to use it?

What are Type Aliases in Kotlin?

typealias is a way to give a new name (alternative name or more meaningful name) to an existing type.

We should use typealias to make our code more readable.

How to use it?

Now, we will understand the use of typeAlias with examples.

Note: typeAlias should be declared from the top level of our Kotlin code and not like inside of a class or a function. Declaring it inside function/class will throw an error.

1.Basic Type Alias:

Here, typealias simply creates a new name (alternative name):
– PersonName for the existing type String
– Person for the existing type Triple<String, String, Int>
– Student
 for the existing type StudentOfTheYear

It allows you to use UserName instead of String , Person instead of Triple<String, String, Int> in your code, making it more readable and self-explanatory.

// Type Alias Declaration
typealias PersonName = String
// give a new name (PersonName) to an existing type (String)

typealias Person = Triple<String, String, Int>
// give a new name (Person) to an existing type (Triple<String, String, Int>)

typealias Student = StudentOfTheYear
// give a new name (stu) to an existing type (Student)

// Type Alias Uses
fun printPersonName(name: PersonName) {
println("Person name: $name")
}

fun fetchUser(): Person {
var person : Person = Person("Gaurav", "Tyagi", 26)
return person
// You can use any way as below
// var person1 : Person = Triple("Gaurav", "Tyagi", 26)
// var person2 : Triple<String, String, Int> = Person("Gaurav", "Tyagi", 26)

}

class StudentOfTheYear ( var name : String,var age: Int) {
fun printInfo() {
println("student name : $name")
println("student age : $age")
}
}

fun main() {
val username: PersonName = "Gaurav"
printPersonName(username)

val person : Person = fetchUser()
println("Person: $person")

var student : Student = Student("Gaurav",25)
student.printInfo()
}

Output:

Person name: Gaurav
Person: (Gaurav, Tyagi, 26)
student name : Gaurav
student age : 25

2.Function Type Alias:

You can also use typealias to name a function type.

Function without using typealias:


fun interface MathOperation {
fun operation(a: Int, b: Int): Int
}


// Object
val subtractionObject : MathOperation = object: MathOperation {
override fun operation(a: Int, b: Int): Int {
return a-b
}
}

// lambda
val additionLambda: MathOperation = MathOperation { a,b -> a+b }

// lambda
val multiplyLambda: (Int,Int) -> Int = { a, b -> a * b}

fun performOperation(a: Int, b: Int, mathOperation : MathOperation) : Int {
return mathOperation.operation(a,b)
}

fun main() {

println("Addition of 10 and 7 --> ${additionLambda.operation(10,7)}")

println("Multiplication of 10 and 7 --> ${multiplyLambda(10,7)}")

var res = performOperation(10,5) { a,b ->
a/b
}

println("Division of 10 and 5 --> ${res}")

res = performOperation(10,5,additionLambda)

println("Addition of 10 and 5 --> ${res}")

res = performOperation(10,5,multiplyLambda)

println("Multiplication of 10 and 5 --> ${res}")

res = subtractionObject.operation(10,5)

println("Subtraction of 10 and 5 --> ${res}")

res = performOperation(10,7,subtractionObject)

println("Subtraction of 10 and 7 --> ${res}")
}

Output:
Addition of 10 and 7 --> 17
Multiplication of 10 and 7 --> 70
Division of 10 and 5 --> 2
Addition of 10 and 5 --> 15
Multiplication of 10 and 5 --> 50
Subtraction of 10 and 5 --> 5
Subtraction of 10 and 7 --> 3

Function with using typealias:

Here, MathOperation is a typealias for a function that takes two integers as parameters and returns an integer.

// Type Alias Declaration
typealias MathOperation = (Int, Int) -> Int

// Type Alias Uses
fun performOperation(a: Int, b: Int, operation: MathOperation): Int {
return operation(a, b)
}

// lambda
val mul:(Int,Int) -> Int = { a, b -> a * b}

// Type Alias Uses
val multiply: MathOperation = { a, b -> a * b}


fun main() {

var result = performOperation(10, 5, multiply)
println("Result of multiplication: $result")

result = performOperation(10, 5) { x: Int, y: Int ->
x-y
}
println("Result of subtraction: $result")


result = performOperation(10, 5,mul)
println("Result of multiplication: $result")

var res = mul(6,4)
println("res ==> $res")

res = multiply(6,4)
println("res ==> $res")
}

Output:

Result of multiplication: 50
Result of subtraction: 5
Result of multiplication: 50
res ==> 24
res ==> 24

3.Higher-Order Function Type Alias:

Here typealias Predicate<T> represents a higher-order function that takes an object of type T and returns a Boolean value. It’s commonly used to define conditions or filters.

// Type Alias Declaration
typealias Predicate<T> = (T) -> Boolean


// Type Alias Uses
fun <T> filterList(list: List<T>, predicate: Predicate<T>): List<T> {
return list.filter(predicate)
}

fun main() {
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

val evenPredicate: Predicate<Int> = { it % 2 == 0 }
var evenNumbers = filterList(numbers, evenPredicate)
println("Even numbers: $evenNumbers")

evenNumbers = filterList(numbers) {
it % 2 == 0
}
println("Even numbers: $evenNumbers")
}

Output:
Even numbers: [2, 4, 6, 8, 10]
Even numbers: [2, 4, 6, 8, 10]

signature of filter method:

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter.html

/**
* Returns a list containing only elements matching the given [predicate].
*
* @sample samples.collections.Collections.Filtering.filter
*/
public inline fun <T> Array<out T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate)
}

4. Two classes with same name:

Have you ever run into a situation where you need to import two classes that have the same name?

For example, check out this Java code, where we are using database model of a user and service model of a user.

import com.example.app.model.User;

public class UserService {
public User translateUser(com.example.app.database.User user) {
return new User(user.getFirst() + " " + user.getLast());
}
}

Since this code deals with two different classes, each called User, we can’t import them both. So instead, we end up fully qualifying one of them.

i) With Kotlin’s Import As, we don’t have to fully qualify it — we can just give it another name when we import it!

import com.example.app.model.User
import com.example.app.database.User as DatabaseUser

class UserService {
fun translateUser(user: DatabaseUser): User =
User("${user.first} ${user.last}")
}

ii) You could also disambiguate the User references with typealias

import com.example.app.model.User

typealias DatabaseUser = com.example.app.database.User

class UserService {
fun translateUser(user: DatabaseUser): User =
User("${user.first} ${user.last}")
}

5. Android specific use-case:

Let’s say we have an RecyclerView adapters and in all of them we need to setup a click listener. The listener will pass the position and the clicked data of that position on the click.

So, let’s create a typeAlias like,

typealias ItemClickListener<T> = (position: Int, data: T) -> Unit

Here, we created a ItemClickListener which takes a position and data of generic. It can be used at different adapters of RecyclerView.

Now, to use this in RecyclerView Adapter for displaying the list of Post we will declare it like,

lateinit var itemClickListener: ItemClickListener<Post>

Now, on the click listener of the item in RecyclerView adapter, we will add,

itemClickListener(position, data)

where, data is the Post data of the item at the specific position which is clicked.

Now, to utilise the listener, we will call it in our view class like,

postAdapter.itemClickListener = { position, data ->
// do something on item click at that position
}

This will get you the position of the list where it was clicked along with the data of type post at that position.

Under the hood

Type aliases don’t introduce new types. For example, the decompiled code for train function will just use a List:

// Kotlin
typealias Dogs = List<Pet.GoodDog>
fun train(dogs: Dogs) { … }

// Decompiled Java code
public static final void train(@NotNull List dogs) { … }

Type aliases don’t introduce new types.

This is all about typealias which you can use to improve readability of your code.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top