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

#typescript
#types

Contact Us

Are you looking for high-tech solutions and software for your company? Contact our specialized staff now and get advice.

If you are looking for support for decision-making, problem-solving and strategy optimization or for the development of solutions and software suitable for your company, you have found it. Contact the Astrorei specialized team now to bring your projects to life.