Kotlinに用意されているtypealiasですが、これは新たな型を作るわけではなく、単に別名を付けてクラスへの参照経路を複数用意してあげるだけのものです。完全に別の型になるというわけではなく、エイリアスとエイリアスを付けられた型同士には互換性があるため、value-objectのような使い方をするためのものではありません。

では、どのような場面で使うのが効果的なのか。以下で例を見ていきます。

同一名前空間上で同名のクラスを使いたい場合

これはtypealiasを使うのにとても適しており、また度々遭遇する場面でもあります。typealiasを使う前と、使ったあとの例を比較してみます。

typealiasを使わない場合

ありがちな話ですが、異なるパッケージの同名クラスを同時に使用したい場合、通常は一方のクラスをFQCNで記述しなければなりません。

import org.springframework.util.StringUtils

fun main(args: Array<String>) {
    StringUtils.capitalize("abcDef123").let {
        println(it) // AbcDef123

        org.apache.commons.lang3.StringUtils.splitByCharacterTypeCamelCase(it).forEach {
            println(it) // Abc Def 123
        }
    }
}

typealiasを使った場合

このような場合にtypealiasを使用すると、すっきり書けて見通しが良くなります。

import org.springframework.util.StringUtils
typealias CommonsStringUtils = org.apache.commons.lang3.StringUtils

fun main(args: Array<String>) {
    StringUtils.capitalize("abcDef123").let {
        println(it) // AbcDef123
        
        CommonsStringUtils.splitByCharacterTypeCamelCase(it).forEach {
            println(it) // Abc Def 123
        }
    }
}

前方互換を維持したままクラス名を変更したい場合

十分に考慮できなかった場合等、後からクラス名を変更したくなる場面というのは少なくありません。クラス名を変更したいにも関わらず、すでに複数の被依存が存在しており、変更が難しくなっているような場合にもtypealiasは役立ちます。

以下のように使うことで、実装をリネームしつつ、古い名前に対する参照に非推奨をマークできます。

リネーム前のクラス

至って普通のクラスですが、名前があまり良くなさそうです。

class UserInfoManagementService {
    ..
}

前方互換を維持したままリネーム

以下のようなにエイリアスを設定して、古いクラス名に非推奨をマークすることで、移行を促すことができます。

class UserService {
    ..
}

@Deprecated("Migrated to UserService")
typealias UserInfoManagementService = UserService

参考