Typealias — cos’è, sintassi e utilizzo in Kotlin

Autore: IT Sectr Pubblicato: 2026-06-23 Tempo di lettura: 7 min

Typealias è un meccanismo di Kotlin per creare un nome alternativo per un tipo esistente. La parola chiave typealias consente di sostituire una dichiarazione di tipo complessa con un alias breve e chiaro senza creare un nuovo tipo. Secondo la documentazione di Kotlin (2026), typealias migliora la leggibilità del codice, specialmente nelle firme di funzioni con tipi funzionali. Typealias rende il codice autodocumentante sostituendo dichiarazioni verbose con tipi nominati chiari.

Punti chiave

  • Typealias — un alias per un tipo esistente che non crea un nuovo tipo
  • Tipi funzionali — typealias sostituisce complessi (T) -> R con nomi leggibili come Callback
  • Generics — typealias supporta parametri generici: typealias ListMapper = (T) -> T
  • Classi annidate — typealias accorcia l’accesso a classi annidate da altri pacchetti
  • Sicurezza dei tipi — typealias non aggiunge controlli in fase di compilazione; l’alias è completamente interscambiabile con l’originale

Cos’è typealias?

Typealias (alias di tipo) è una dichiarazione che introduce un nome alternativo per un tipo esistente. Sintassi: typealias NuovoNome = TipoEsistente. Dopo la dichiarazione, NuovoNome può essere usato ovunque ci si aspetti TipoEsistente — il compilatore li tratta come lo stesso tipo. A livello di bytecode, typealias non lascia tracce: tutte le informazioni sull’alias vengono cancellate in fase di compilazione.

Lo scopo principale di typealias è migliorare la leggibilità del codice. Invece di una firma verbosa fun process(callback: (Result) -> Unit), si può scrivere typealias Callback = (Result) -> Unit e usare Callback come tipo di parametro. Ciò è particolarmente utile quando lo stesso tipo funzionale si ripete in più punti del codice: l’alias funge da punto di definizione unico e documenta lo scopo del tipo.

Typealias non crea un nuovo tipo — è solo un sinonimo. Le variabili di tipo Callback e (Result) -> Unit sono completamente interscambiabili. Il compilatore non genererà un errore se una lambda viene passata direttamente a una funzione che si aspetta Callback. Questo distingue typealias da inline class (value class), che crea un nuovo tipo wrapper con controllo in fase di compilazione. Typealias è rinominare, non incapsulare.

Typealias per tipi funzionali

Il caso d’uso più comune di typealias in Kotlin sono i tipi funzionali. Firma lunghe come (Int, String) -> Boolean o (List) -> Result rendono il codice difficile da leggere. Typealias le trasforma in nomi brevi e significativi che documentano lo scopo della funzione: typealias Validator = (String) -> Boolean specifica che si tratta di un validatore di stringhe.

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

Nell’esempio, il typealias UserFilter nasconde il complesso tipo funzionale (List) -> List dietro un nome corto. La firma di findUsers diventa leggibile: “accetta UserFilter, restituisce List”. Il typealias OnClickListener fa assomigliare il codice a una dichiarazione di interfaccia ma senza l’overhead di creare un’interfaccia o una classe astratta separata. Nel frattempo, lambda e funzioni anonime continuano a funzionare normalmente — typealias non richiede modifiche al codice chiamante.

Typealias con generics

Typealias supporta parametri generici, rendendolo ancora più flessibile. Si può definire typealias Mapper = (T) -> R e usarlo con qualsiasi tipo. Il compilatore sostituisce tipi specifici ai parametri a ogni utilizzo dell’alias, preservando la piena sicurezza dei tipi.

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

Nell’elenco, Mapper è un alias generico per qualsiasi trasformazione da T a R. Provider è un fornitore di valore (una fabbrica senza argomenti). ListTransformer è una funzione di trasformazione di liste. Quando si chiama processNumbers(mapper: Mapper), il compilatore espande l’alias in (Int) -> String. I generics rendono typealias uno strumento universale adatto a qualsiasi contesto senza duplicare dichiarazioni.

Typealias per nomi annidati e lunghi

Le classi annidate e i tipi parametrizzati lunghi sono un altro ambito in cui typealias semplifica notevolmente il codice. Se una classe è profonda in una gerarchia di annidamento (Outer.Inner.Nested), riferirsi ad essa con il nome completo ingombra il codice. Typealias accorcia tale accesso e lo rende più leggibile. Ciò è particolarmente rilevante per le classi di librerie di terze parti con nomi lunghi.

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
}

Nell’esempio, NetworkError è un alias per la classe annidata NetworkResponse.Error. Importando il typealias, si può usare NetworkError come un tipo normale senza rivelare la gerarchia di annidamento. JsonMap documenta che la mappa rappresenta un oggetto JSON. UserId chiarisce lo scopo di Long in un contesto specifico — il lettore capisce immediatamente che si tratta di un identificatore utente, non di un numero arbitrario. Tuttavia, typealias non impedisce di passare un Long semplice dove ci si aspetta UserId — per questo è necessaria una value class.

Typealias vs Inline Class: differenze

Typealias e inline class (value class) risolvono problemi diversi, sebbene entrambi introducano un nuovo nome per un tipo. Typealias è solo un sinonimo: una variabile di tipo UserId = Long accetta qualsiasi Long senza controllo. Inline class incapsula un valore in un nuovo tipo che viene controllato in fase di compilazione: non è possibile passare un Long semplice dove ci si aspetta una inline class UserId senza conversione esplicita.

CaratteristicaTypealiasInline class
Nuovo tipoNo — sinonimo dell’originaleSì — nuovo tipo con controlli
PrestazioniZero — completamente cancellatoZero — wrapper rimosso nel bytecode
EreditarietàNoNo (classe finale)
Metodi propriNoSì — è possibile dichiarare funzioni
Sicurezza dei tipiNo — interscambiabile con l’originaleSì — il compilatore distingue i tipi

La tabella mostra la differenza tra i due meccanismi. Typealias è adatto per nomi concisi e documentazione del codice quando non è richiesta una tipizzazione stretta. L’inline class tramite la parola chiave value class (precedentemente inline class) è necessaria quando è importante distinguere valori semanticamente diversi dello stesso tipo primitivo. Ad esempio, UserId e OrderId sono entrambi Long, ma passare l’uno dove ci si aspetta l’altro è un errore logico che la value class previene in fase di compilazione.

Domande frequenti

In cosa typealias si differenzia da import alias?

Import alias (import com.example.LongName as Short) funziona a livello di importazione — accorcia il nome solo nel file corrente. Typealias dichiara un alias globale disponibile in tutto il progetto dopo l’importazione.

Si può usare typealias per creare un tipo ricorsivo?

Sì, typealias supporta definizioni ricorsive per tipi funzionali, ma con cautela: typealias Rec = (T) -> Rec funziona, ma i riferimenti ricorsivi a object no. Il compilatore verifica i cicli e produce un errore per definizioni infinite.

Typealias influisce sulle prestazioni?

No, typealias viene completamente cancellato in fase di compilazione. Il tipo originale viene utilizzato a livello di bytecode e runtime senza alcun wrapper. Le prestazioni sono identiche all’uso diretto del tipo originale.

Qual è il livello massimo di annidamento per typealias?

Typealias può riferirsi a un altro typealias — questa è chiamata catena di alias. La profondità della catena è formalmente illimitata, ma per la leggibilità si raccomandano non più di 2–3 livelli. Il compilatore risolve completamente la catena in fase di analisi.

Si può dichiarare typealias all’interno di una funzione?

No, typealias è una dichiarazione di livello superiore o un membro di una classe/oggetto. Typealias non può essere dichiarato all’interno di funzioni. Per l’accorciamento locale dei tipi, usa import alias all’interno del file o posiziona il typealias a livello di modulo.

Riepilogo

  • Typealias — un sinonimo per un tipo esistente che non crea un nuovo tipo e viene cancellato in fase di compilazione
  • Tipi funzionali — il caso d’uso principale: typealias sostituisce (T) -> R con un nome leggibile come Callback
  • Generics in typealias permettono di creare alias generici Mapper per qualsiasi tipo
  • Classi annidate — typealias accorcia l’accesso a tipi profondamente annidati e nomi lunghi da librerie
  • Sicurezza dei tipi assente: typealias è completamente interscambiabile con il tipo originale
  • Value class — un’alternativa a typealias quando è necessario un controllo stretto dei tipi a costo zero in runtime
  • Leggibilità — il principale vantaggio: nomi di tipo significativi rendono il codice autodocumentante senza overhead

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche