Typescript 4.9 ha aggiunto l'operatore satisfies
, che permette di vincolare l'assegnazione a valori che soddisfano un certo tipo. Ad esempio:
// se scegliamo "string", possiamo usare solo valori che sono stringhe
const myVar1 = "hello" satisfies string;
const myVar2 = 42 satisfies string; // errore, 42 non è una stringa
// anche definendo la costante di tipo string forziamo lo stesso
// comportamento
const myVar3: string = "hello";
Ma allora cosa cambia? L'utilità di satisfies
è che permette di restringere i valori assegnabili senza "allargare/cambiare" il tipo della variabile risultante. In altri termini:
const myHello = "hello" as const; // tipo "hello" non string
const myVar1 = myHello satisfies string;
// myVar1 è di tipo "hello", quindi più preciso, e non string
// ma in più sappiamo che ci vincoliamo ad assegnargli una string
// e non altri valori
Un caso reale (ipotizzando tsconfig option "strict"=true):
// voglio modellare le variabili d'ambiente per la connessione a db
type EnvironmentVariableName = "DB_HOST" | "DB_PASSWORD";
// voglio costruire un oggetto con un valore di default per ogni
// variabile d'ambiente
const values1 = {
DB_HOST: "host",
DB_PASSWORD: "password",
};
// come fare a tipizzarlo affinché abbia solo le chiavi con i nomi
// delle variabili d'ambiente?
const values2: Record<EnvironmentVariableName, string> = {
DB_HOST: "host",
DB_PASSWORD: "password",
};
// ora l'oggetto è correttamente tipizzato, ma cosa succede se non
// abbiamo un default per una delle chiavi?
const values3: Record<EnvironmentVariableName, string> = {
DB_HOST: "host",
DB_PASSWORD: undefined,
}; // -> errore, non possiamo assegnare undefined a string
// prima soluzione: far si che le chiavi possano essere undefined
const values4: Record<EnvironmentVariableName, string | undefined> = {
DB_HOST: "host",
DB_PASSWORD: undefined,
};
// ora però quando accedo a una qualsiasi chiave, anche quelle per cui
// ho indicato un valore ottengo un qualcosa di potenzialmente
// undefined
console.log(values4.DB_HOST);
// string | undefined, anche se abbiamo usato il valore "host"
// soluzione con satisfies
const values5 = {
DB_HOST: "host",
DB_PASSWORD: undefined,
} satisfies Record<EnvironmentVariableName, string | undefined>;
// in questo modo il type system ci forzerà ad assegnare un valore
// compatibile con i nostri requisiti mentre il valore delle singole
// chiavi sarà precisamente come l'abbiamo valorizzato
console.log(values5.DB_HOST); // string, "host"
console.log(values5.DB_PASSWORD); // undefined
Per un altro ottimo esempio si rimanda all'articolo ufficiale di annuncio del nuovo operatore in typescript 4.9.
Kristian Notari
Se cerchi supporto per i processi di decision-making, problem-solving, strategy optimization o per lo sviluppo di soluzioni e software adatti alla tua azienda lo hai trovato. Contatta ora il team specializzato di Astrorei per dare vita ai tuoi progetti.
Fissa un appuntamento!
Carlo Vassallo