astrorei

L'operatore "satisfies"

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

Kristian Notari

Contattaci

Cerchi soluzioni e software ad alta tecnologia per la tua azienda? Contatta ora il nostro staff specializzato ed ottieni una consulenza.

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.