---
title: "Type Alias em Kotlin: O que É e Como Funciona | Kotlin Brasil"
url: "https://kotlin.dev.br/glossario/type-alias/"
markdown_url: "https://kotlin.dev.br/glossario/type-alias.MD"
description: "Entenda o que são type aliases em Kotlin, como criar nomes alternativos para tipos complexos, sintaxe, exemplos práticos e erros comuns."
date: "2025-08-14"
author: "Karina Melo"
---

# Type Alias em Kotlin: O que É e Como Funciona | Kotlin Brasil

Entenda o que são type aliases em Kotlin, como criar nomes alternativos para tipos complexos, sintaxe, exemplos práticos e erros comuns.


## O que é Type Alias em Kotlin?

Um type alias em Kotlin é um nome alternativo para um tipo existente. Ele não cria um novo tipo, mas oferece uma forma mais legivel de referenciar tipos complexos ou longos. Declarado com a palavra-chave `typealias`, esse recurso melhora a legibilidade do código sem impacto em performance, pois o compilador substitui o alias pelo tipo original durante a compilação.

Type aliases são especialmente úteis quando você trabalha com tipos genericos compostos, funções de ordem superior com assinaturas longas ou tipos de plataformas externas que possuem nomes pouco descritivos.

## Sintaxe básica

A declaracao de um type alias e feita no nível do arquivo (top-level), fora de classes ou funções:

```kotlin
typealias ListaDeUsuarios = List<Usuario>
typealias Callback<T> = (T) -> Unit
typealias MapaDeNotas = Map<String, List<Double>>
```

Apos a declaracao, você pode usar o alias em qualquer lugar onde usaria o tipo original:

```kotlin
data class Usuario(val nome: String, val idade: Int)

typealias ListaDeUsuarios = List<Usuario>

fun exibirUsuarios(usuarios: ListaDeUsuarios) {
    usuarios.forEach { println("${it.nome} - ${it.idade} anos") }
}

fun main() {
    val lista: ListaDeUsuarios = listOf(
        Usuario("Ana", 28),
        Usuario("Carlos", 35)
    )
    exibirUsuarios(lista)
}
```

## Exemplos práticos

### Simplificando tipos de função

Tipos de função em Kotlin podem ficar extensos quando possuem vários parametros. Type aliases resolvem isso:

```kotlin
typealias Validador<T> = (T) -> Boolean
typealias Transformador<T, R> = (T) -> R
typealias GerenciadorDeErro = (Exception) -> Unit

fun <T> filtrar(lista: List<T>, validador: Validador<T>): List<T> {
    return lista.filter(validador)
}

fun <T, R> mapear(lista: List<T>, transformador: Transformador<T, R>): List<R> {
    return lista.map(transformador)
}

fun executarComTratamento(bloco: () -> Unit, onErro: GerenciadorDeErro) {
    try {
        bloco()
    } catch (e: Exception) {
        onErro(e)
    }
}

fun main() {
    val numeros = listOf(1, 2, 3, 4, 5, 6)

    val pares = filtrar(numeros) { it % 2 == 0 }
    println(pares) // [2, 4, 6]

    val textos = mapear(numeros) { "Numero $it" }
    println(textos) // [Numero 1, Numero 2, ...]

    executarComTratamento(
        bloco = { println("Executando operacao") },
        onErro = { println("Erro: ${it.message}") }
    )
}
```

### Trabalhando com tipos genericos complexos

```kotlin
typealias ResultadoApi<T> = Pair<Int, T?>
typealias TabelaDePrecos = Map<String, Map<String, Double>>
typealias MatrizInteira = Array<IntArray>

fun buscarUsuario(id: Int): ResultadoApi<Usuario> {
    return if (id > 0) {
        200 to Usuario("Ana", 28)
    } else {
        404 to null
    }
}

fun criarTabelaPrecos(): TabelaDePrecos {
    return mapOf(
        "eletronicos" to mapOf(
            "notebook" to 4500.00,
            "smartphone" to 2800.00
        ),
        "livros" to mapOf(
            "kotlin-em-acao" to 89.90,
            "clean-code" to 75.00
        )
    )
}

fun criarMatriz(linhas: Int, colunas: Int): MatrizInteira {
    return Array(linhas) { IntArray(colunas) }
}
```

### Type alias para inner classes e nested classes

```kotlin
class Repositorio {
    sealed class Resultado<out T> {
        data class Sucesso<T>(val dados: T) : Resultado<T>()
        data class Erro(val mensagem: String) : Resultado<Nothing>()
        data object Carregando : Resultado<Nothing>()
    }
}

// Sem alias: Repositorio.Resultado.Sucesso<Usuario>
// Com alias:
typealias RepoResultado<T> = Repositorio.Resultado<T>
typealias RepoSucesso<T> = Repositorio.Resultado.Sucesso<T>
typealias RepoErro = Repositorio.Resultado.Erro

fun buscarDados(): RepoResultado<String> {
    return RepoSucesso("Dados carregados")
}

fun main() {
    when (val resultado = buscarDados()) {
        is RepoSucesso -> println(resultado.dados)
        is RepoErro -> println(resultado.mensagem)
        is Repositorio.Resultado.Carregando -> println("Carregando...")
    }
}
```

### Type alias com tipos de plataforma

Quando você integra Kotlin com bibliotecas Java ou APIs externas, os nomes de tipos podem ser longos e pouco descritivos:

```kotlin
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ScheduledExecutorService

typealias CacheDeTokens = ConcurrentHashMap<String, Pair<String, Long>>
typealias Agendador = ScheduledExecutorService

class GerenciadorDeTokens(
    private val cache: CacheDeTokens = CacheDeTokens(),
    private val agendador: Agendador
) {
    fun armazenar(chave: String, token: String, expiracao: Long) {
        cache[chave] = token to expiracao
    }

    fun obter(chave: String): String? {
        val entrada = cache[chave] ?: return null
        return if (System.currentTimeMillis() < entrada.second) entrada.first else null
    }
}
```

## Quando usar type alias

Type aliases são mais úteis nos seguintes cenários:

- **Tipos genericos profundamente aninhados** como `Map<String, List<Pair<Int, Double>>>` que aparecem em vários pontos do código.
- **Assinaturas de função repetitivas** quando um mesmo tipo de callback e usado em múltiplas funções.
- **Nomes de dominio mais expressivos** para tornar o código mais legivel no contexto do negócio, como `typealias CPF = String` ou `typealias Reais = Double`.
- **Encurtar referências a classes internas** de bibliotecas ou de seus próprios modulos.
- **Migração gradual** quando você quer renomear um tipo sem alterar todo o código de uma vez.

## Casos de Uso no Mundo Real

1. **Camadas de repositório e servico**: em projetos com arquitetura em camadas, type aliases simplificam tipos de retorno complexos como `Flow<Result<List<Usuario>>>` ou `suspend () -> Result<List<Produto>>`. Isso torna as assinaturas de funções dos repositórios mais legiveis e consistentes em toda a base de código.

2. **Callbacks em SDKs e bibliotecas**: bibliotecas que expõe APIs com callbacks usam type aliases para dar nomes semanticos aos tipos de função. Por exemplo, `typealias OnItemClick<T> = (T, Int) -> Unit` e mais expressivo do que repetir a assinatura completa em cada função publica da API.

3. **Mapeamento de entidades entre camadas**: projetos que seguem Clean Architecture frequentemente definem aliases para mapear entre tipos de diferentes camadas, como `typealias EntityMapper<Domain, Data> = (Data) -> Domain`, criando uma convencao clara para todas as funções de mapeamento.

4. **integração com bibliotecas Java**: ao usar bibliotecas Java que possuem tipos com nomes longos ou pouco descritivos (como `ConcurrentHashMap<String, List<WeakReference<Callback>>>>`), type aliases permitem criar nomes mais concisos e contextualizados no dominio do projeto Kotlin.

## Boas Praticas

- Use type aliases apenas quando o tipo original aparece em múltiplos lugares e sua complexidade prejudica a leitura. Criar aliases para tipos simples como `String` ou `Int` raramente agrega valor.
- Escolha nomes que reflitam o dominio do negócio, não a estrutura tecnica. Prefira `typealias TabelaDePrecos = Map<String, Double>` em vez de `typealias StringDoubleMap = Map<String, Double>`.
- Quando precisar de seguranca de tipos real (impedir que um `CPF` seja usado onde se espera um `Email`), use value classes em vez de type aliases. O alias e apenas um apelido e não impede substituicoes indevidas.
- Declare todos os type aliases no nivel do arquivo (top-level), preferencialmente agrupados em um arquivo dedicado como `TypeAliases.kt` ou proximo aos tipos que eles referenciam, facilitando a descoberta.
- Evite criar aliases para tipos que já sao claros no contexto. O excesso de aliases pode dificultar a navegação no código e confundir desenvolvedores que precisam descobrir o tipo real por tras do alias.

## Perguntas Frequentes

**P: Type alias cria um novo tipo ou apenas um apelido?**
R: Apenas um apelido. O compilador substitui o alias pelo tipo original durante a compilação. Isso significa que `typealias CPF = String` permite usar um `CPF` em qualquer lugar que aceite `String` e vice-versa. Nao há verificação de tipo adicional em tempo de compilação.

**P: Posso declarar um type alias dentro de uma classe ou função?**
R: Nao. Type aliases em Kotlin só podem ser declarados no nivel do arquivo (top-level). Tentar declarar dentro de uma classe, objeto ou função resulta em erro de compilação. Essa restricao existe porque aliases sao resolvidos em tempo de compilação e precisam ter escopo global.

**P: Type alias tem algum impacto em performance?**
R: Nenhum. O alias e completamente eliminado durante a compilação. No bytecode final, apenas o tipo original aparece. Nao há alocacao extra, indireção ou qualquer custo em tempo de execução.

**P: Quando devo usar type alias em vez de value class?**
R: Use type alias quando o objetivo e apenas melhorar a legibilidade de tipos complexos sem necessidade de seguranca de tipos adicional. Use value class quando você precisa que o compilador impeca a troca acidental de valores com o mesmo tipo subjacente, como evitar que um `UserId` seja passado onde se espera um `ProductId`.

## Erros comuns

### Confundir type alias com novo tipo

```kotlin
typealias CPF = String
typealias Email = String

fun enviarPara(email: Email) {
    println("Enviando para $email")
}

fun main() {
    val cpf: CPF = "123.456.789-00"
    enviarPara(cpf) // Compila sem erro! CPF e Email são ambos String
}
```

O type alias não cria um novo tipo. `CPF` e `Email` são intercambiaveis porque ambos são `String`. Se você precisa de segurança de tipos, use value classes (inline classes) em vez de type aliases.

### Declarar dentro de funções ou classes

```kotlin
// ERRADO: type alias nao pode ser local
fun processar() {
    typealias Dados = List<String> // erro de compilacao
}

// CORRETO: declarar no nível do arquivo
typealias Dados = List<String>
fun processar(dados: Dados) { /* ... */ }
```

### Alias para tipos com variancia conflitante

```kotlin
open class Animal
class Cachorro : Animal()

typealias ListaAnimais = MutableList<Animal>

fun main() {
    val cachorros: MutableList<Cachorro> = mutableListOf(Cachorro())
    // val animais: ListaAnimais = cachorros // Erro: tipos incompativeis
    // MutableList<Cachorro> nao e subtipo de MutableList<Animal>
}
```

O alias não altera as regras de variancia do tipo original. `MutableList` e invariante, entao `MutableList<Cachorro>` não e subtipo de `MutableList<Animal>`, independentemente do alias.

### Excesso de aliases

Criar aliases demais pode dificultar a navegação no código. Se o tipo original já e claro, o alias adiciona uma camada desnecessaria de indirecao. Use com moderacao.

## Termos relacionados

- **Value class (inline class)**: cria um tipo wrapper com segurança de tipos em tempo de compilação, diferente do type alias que e apenas um apelido.
- **Generics**: sistema de tipos parametrizados que frequentemente gera tipos longos beneficiados por aliases.
- **Função de ordem superior**: funções que recebem ou retornam outras funções, cujas assinaturas são frequentemente simplificadas com aliases.
- **Data class**: tipo de classe em Kotlin para armazenar dados, frequentemente referenciada por aliases quando usada em coleções.
- **Sealed class**: hierarquia restrita de tipos que pode ter aliases para facilitar a referência a subtipos.

## Conclusão

Type aliases são uma ferramenta simples mas eficaz para melhorar a legibilidade do código Kotlin. Eles não criam novos tipos nem adicionam overhead em tempo de execução. Use-os para simplificar tipos genericos complexos, assinaturas de função longas e referências a classes profundamente aninhadas. Quando precisar de segurança de tipos real, considere value classes como alternativa. O equiibrio entre legibilidade e clareza e a chave para usar type aliases de forma produtiva.
