TypeScript estende le classi già presenti in JavaScript aggiungendo funzionalità dedicate alla tipizzazione e al controllo dell'accesso alle proprietà e ai metodi.
Possiamo quindi specificare il tipo dei campi di una classe, dei parametri del costruttore e dei valori restituiti dai metodi. Inoltre, TypeScript mette a disposizione i modificatori di visibilità public, private e protected, che permettono di stabilire da quali parti del codice è possibile accedere ai membri di una classe.
La sintassi di una classe TypeScript è simile a quella di JavaScript:
class Persona {
nome: string;
eta: number;
constructor(nome: string, eta: number) {
this.nome = nome;
this.eta = eta;
}
}In questo esempio:
nome è un campo di tipo string, eta è un campo di tipo number. this.nome e this.eta inizializzano i campi dell'istanza. Possiamo quindi creare un oggetto della classe:
const persona = new Persona("Andrea", 30);TypeScript controlla che gli argomenti passati al costruttore siano compatibili con i tipi dichiarati:
const persona = new Persona("Andrea", "30"); // ErroreIn questo caso viene segnalato un errore perché eta richiede un number.
Anche i metodi possono avere parametri e valori di ritorno tipizzati. Ad esempio:
class Persona {
nome: string;
constructor(nome: string) {
this.nome = nome;
}
saluta(): string {
return `Ciao, sono ${this.nome}`;
}
}Il metodo saluta() non riceve parametri e restituisce una string.
Possiamo anche lasciare che TypeScript determini automaticamente il tipo di ritorno quando questo può essere dedotto facilmente:
class Persona {
nome: string;
constructor(nome: string) {
this.nome = nome;
}
saluta() {
return `Ciao, sono ${this.nome}`;
}
}In questo caso TypeScript deduce automaticamente che il metodo restituisce una string.
TypeScript mette a disposizione 3 diversi modificatori di visibilità: public, private e protected.
Il modificatore public indica che un membro della classe può essere utilizzato da qualsiasi parte del codice.
Ad esempio:
class Persona {
public nome: string;
constructor(nome: string) {
this.nome = nome;
}
}Possiamo accedere alla proprietà dall'esterno:
const persona = new Persona("Andrea");
console.log(persona.nome);public è il comportamento predefinito dei membri delle classi TypeScript. Per questo motivo possiamo anche ometterlo.
Il modificatore private limita l'accesso a un membro della classe.
Ad esempio:
class Conto {
private saldo: number;
constructor(saldo: number) {
this.saldo = saldo;
}
}Il campo saldo può essere utilizzato all'interno della classe:
class Conto {
private saldo: number;
constructor(saldo: number) {
this.saldo = saldo;
}
mostraSaldo(): number {
return this.saldo;
}
}Ma non possiamo accedervi direttamente dall'esterno:
const conto = new Conto(1000);
console.log(conto.saldo); // ErroreTypeScript segnala un errore perché saldo è private.
Possiamo invece utilizzare il metodo pubblico:
console.log(conto.mostraSaldo());In questo modo la classe controlla come il proprio stato interno viene esposto all'esterno.
La visibilità protected è simile a private, ma permette l'accesso anche alle classi che estendono quella originale.
Per esempio:
class Persona {
protected nome: string;
constructor(nome: string) {
this.nome = nome;
}
}Una classe derivata può utilizzare nome:
class Studente extends Persona {
mostraNome(): string {
return this.nome;
}
}Possiamo quindi scrivere:
const studente = new Studente("Andrea");
console.log(studente.mostraNome());Tuttavia, nome non è accessibile direttamente dall'esterno (ad esempio, usando studente.nome).
TypeScript offre una sintassi abbreviata per dichiarare e inizializzare contemporaneamente i campi della classe.
In questo esempio, possiamo utilizzare direttamente i modificatori nei parametri del costruttore:
class Persona {
constructor(
public nome: string,
public eta: number
) {}
}L'esempio abbrevia questa scrittura più lunga:
class Persona {
nome: string;
eta: number;
constructor(nome: string, eta: number) {
this.nome = nome;
this.eta = eta;
}
}Infatti, TypeScript crea automaticamente i campi e assegna loro i valori ricevuti dal costruttore.
Possiamo quindi creare normalmente un'istanza:
const persona = new Persona("Andrea", 30);
console.log(persona.nome);
console.log(persona.eta);Questa sintassi è chiamata, in gergo, parameter property e permette di ridurre notevolmente il codice necessario per inizializzare i campi.
Il modificatore readonly può essere applicato ai campi di una classe per impedire che vengano riassegnati dopo la loro inizializzazione.
Per esempio:
class Persona {
readonly id: number;
nome: string;
constructor(id: number, nome: string) {
this.id = id;
this.nome = nome;
}
}Possiamo modificare nome, ma non possiamo riassegnare id:
const persona = new Persona(1, "Andrea");
persona.nome = "Luca";
persona.id = 2; // ErroreTypeScript segnala un errore perché id è readonly.
Un campo readonly può quindi essere assegnato durante l'inizializzazione, ad esempio nel costruttore, ma non successivamente.
Possiamo combinare readonly con la sintassi abbreviata che abbiamo visto precedentemente:
class Persona {
constructor(
public readonly id: number,
public nome: string
) {}
}