Moduli e librerie esterne in TypeScript

Quando un progetto TypeScript cresce, è normale dividere il codice in più file e utilizzare librerie esterne. In questi casi TypeScript deve sapere quali tipi vengono esportati da un modulo e quali tipi sono disponibili all'interno di una libreria.

Per gestire queste situazioni possiamo utilizzare import type e export type, installare librerie Javascript e i pacchetti di tipizzazione @types.

Esportare elementi in un progetto

Per impostazione predefinita, qualsiasi variabile, funzione o tipo dichiarato in un file TypeScript è disponibile solo localmente e non è visibile al resto del progetto.

Possiamo esportare un alias di tipo da un file utilizzando export type, così da poterlo rendere visibile in altri file del progetto in TypeScript.

Per esempio, nel file utente.ts:

export type Utente = {
    id: number;
    nome: string;
    email: string;
};

Il tipo Utente può essere utilizzato da altri file del progetto.

Per esempio, nel file app.ts possiamo importare il tipo:

import type { Utente } from "./utente";

Possiamo quindi utilizzare il tipo all'interno di app.ts:

const utente: Utente = {
    id: 1,
    nome: "Andrea",
    email: "[email protected]"
};

In questo modo il tipo viene definito una sola volta e può essere riutilizzato in più parti del progetto.

Esportare un'interfaccia

Lo stesso meccanismo che abbiamo visto può essere utilizzato con le interfacce:

export interface Prodotto {
    id: number;
    nome: string;
    prezzo: number;
}

Possiamo importarla in un altro file:

import type { Prodotto } from "./prodotto";

Ora possiamo utilizzare l'interfaccia normalmente:

const prodotto: Prodotto = {
    id: 1,
    nome: "Tastiera",
    prezzo: 49.99
};

Importare tipi in un file

Quando importiamo esclusivamente un tipo possiamo utilizzare la sintassi:

import type {tipo} from "./file";

import type comunica esplicitamente a TypeScript che quell'importazione serve soltanto per il tipo e forza il compilatore a eliminare completamente l'istruzione dal file JavaScript finale.

Ad esempio, possiamo importare il tipo Utente così:

import type { Utente } from "./utente";

function stampaUtente(utente: Utente): void {
    console.log(utente.nome);
}

Utente viene utilizzato soltanto come tipo e non come valore durante l'esecuzione del programma.

Differenza tra import e import type

In TypeScript possiamo utilizzare sia import sia import type, a seconda di ciò che vogliamo importare. Possiamo avere nello stesso modulo sia valori sia tipi:

utente.ts
export type Utente = {
    id: number;
    nome: string;
};

export function creaUtente(nome: string): Utente {
    return {
        id: 1,
        nome
    };
}

Nel file che importa questi elementi possiamo scrivere:

import { creaUtente } from "./utente";
import type { Utente } from "./utente";

La differenza principale è questa:

  • import { creaUtente } importa un valore utilizzato durante l'esecuzione.
  • import type { Utente } importa esclusivamente un tipo.

È possibile anche utilizzare una singola importazione:

import { creaUtente, type Utente } from "./utente";

Importare librerie

Per molte librerie JavaScript esistono pacchetti separati che contengono le relative definizioni di tipo. Questi pacchetti vengono generalmente pubblicati con il nome: @types/libreria

Per esempio, se utilizziamo una libreria JavaScript chiamata libreria, possiamo verificare se esiste il relativo pacchetto:

npm install --save-dev @types/libreria

Il pacchetto contiene principalmente informazioni che permettono a TypeScript di conoscere l'API della libreria.

La libreria JavaScript rimane quella effettivamente eseguita dall'applicazione; le definizioni @types servono invece al controllo statico durante lo sviluppo e la compilazione.

DefinitelyTyped

Uno dei principali progetti che raccoglie definizioni di tipo per librerie JavaScript è DefinitelyTyped. Il repository contiene migliaia di definizioni per librerie che non forniscono direttamente i propri tipi.

I pacchetti presenti in DefinitelyTyped vengono normalmente distribuiti attraverso npm con il prefisso @types/. Ad esempio:

npm install --save-dev @types/lodash

Questo comando installa @types/lodash, che contiene le definizioni TypeScript per la libreria JavaScript lodash.

Non tutte le librerie necessitano però di un pacchetto @types: molte librerie moderne includono direttamente i propri file di dichiarazione.

Prova!Completa gli spazi vuoti con il testo appropriato.
// Importa il tipo Utente
type { Utente } "./utente";

Prova! Scegli l'opzione corretta tra quelle elencate.
// Esporta il tipo
________ Prodotto = {
    id: number;
    nome: string;
};