Diego Betto's Blog
Foto di Ayush Kumar su Unsplash

Diego Betto · 7 settembre 2026 · 3 min di lettura

TypeScript: l'operatore satisfies, a cosa serve davvero

L'operatore satisfies di TypeScript spiegato con esempi pratici: perché as e le annotazioni esplicite fanno perdere inferenza, e come satisfies risolve il problema senza compromessi.

Condividi:XLinkedInFacebookWhatsApp

Quando definisci un oggetto di configurazione in TypeScript ti trovi spesso davanti a un compromesso che sembra inevitabile: o controlli che la forma dell’oggetto sia corretta, o mantieni i tipi letterali più precisi dei singoli valori. Prima di satisfies (TypeScript 4.9), scegliere l’uno significava perdere l’altro.

Il problema: annotazione esplicita vs inferenza

Prendi una palette di colori, dove ogni valore deve essere una stringa esadecimale valida (`#${string}`):

type Palette = Record<string, `#${string}`>;

const colori: Palette = {
  primario: "#3366ff",
  secondario: "#ff9900",
};

// colori.primario è tipizzato come `#${string}` — non come "#3366ff"
colori.primario.toUpperCase(); // ok, ma nessun autocomplete sul valore esatto

L’annotazione : Palette verifica correttamente la forma (ogni valore deve iniziare con #), ma TypeScript allarga ogni proprietà al tipo dichiarato nel Record. Il risultato: perdi l’informazione che colori.primario vale esattamente "#3366ff", e con essa autocomplete e controlli più stretti su quel valore specifico.

La tentazione: usare as

L’alternativa ovvia è non annotare affatto e lasciare che TypeScript inferisca:

const colori = {
  primario: "#3366ff",
  secondario: "#ff9900",
} as const;

Qui riottieni i tipi letterali precisi, ma perdi il controllo opposto: nessun errore se scrivi un valore che non rispetta la forma attesa.

const coloriRotti = {
  primario: "#3366ff",
  secondario: "arancione", // non è un valore esadecimale, ma nessun errore
} as const;

Con as const TypeScript si limita a congelare i tipi che vede, senza validarli contro nessuna forma. as Palette avrebbe lo stesso problema in forma diversa: as dice al compilatore “fidati di me”, non “controlla che questo rispetti la forma X”.

La soluzione: satisfies

satisfies fa esattamente quello che manca a entrambi gli approcci: valida che il valore rispetti un tipo, senza allargarlo a quel tipo.

const colori = {
  primario: "#3366ff",
  secondario: "#ff9900",
} satisfies Palette;

colori.primario; // tipo: "#3366ff" — letterale, non `#${string}`

E se un valore non rispetta la forma attesa, l’errore torna a comparire — a differenza di as const:

const coloriRotti = {
  primario: "#3366ff",
  secondario: "arancione",
  //           ~~~~~~~~~~
  // error! Type '"arancione"' is not assignable to type '`#${string}`'.
} satisfies Palette;

Ottieni entrambe le cose: validazione della forma in fase di compilazione, e inferenza del tipo più preciso possibile per ogni valore.

💡 Consiglio

Un caso pratico dove questo conta davvero: un oggetto di configurazione con chiavi note (per cui vuoi autocomplete preciso, es. config.endpoints.utenti) ma che deve anche rispettare un’interfaccia comune (es. ogni endpoint deve avere method e path). satisfies EndpointConfig ti dà entrambe le garanzie nello stesso punto, senza dover scegliere.

Excess property checks: un altro vantaggio silenzioso

satisfies mantiene anche il controllo delle proprietà in eccesso, che con un’annotazione esplicita a volte si perde per via del widening:

interface Opzioni {
  timeout: number;
}

function configura(opzioni: Opzioni) {
  /* ... */
}

const mieOpzioni = {
  timeout: 3000,
  retries: 3, // proprietà non prevista da Opzioni
} satisfies Opzioni;
//   ~~~~~~~
// error! Object literal may only specify known properties,
// and 'retries' does not exist in type 'Opzioni'.

Lo stesso controllo che avresti passando il letterale direttamente a configura(...), ma applicato al momento della dichiarazione della costante — utile quando vuoi riusare quell’oggetto altrove prima ancora di passarlo a una funzione.

Quando preferire comunque un’interfaccia esplicita

satisfies non sostituisce sempre un’annotazione di tipo classica. Se hai bisogno che una variabile sia trattata come quel tipo ovunque venga usata — ad esempio un valore che può cambiare forma più avanti nel codice, o un parametro di funzione dove vuoi che il chiamante rispetti esattamente l’interfaccia dichiarata, non il tipo più stretto inferito — l’annotazione esplicita resta la scelta giusta. satisfies è per il caso specifico in cui vuoi validare e preservare l’inferenza sullo stesso valore, tipicamente in oggetti di configurazione, mappe di route o costanti che poi consumi altrove sfruttando i loro tipi letterali.

Vale la pena leggere anche l’articolo su NoInfer, un’altra utility introdotta di recente per controllare — nella direzione opposta — come e quando TypeScript deve inferire i generici.

Condividi:XLinkedInFacebookWhatsApp
Diego Betto

Scritto da

Diego Betto

Co-Fondatore & CTO presso PAPION. Senior full-stack engineer specializzato in React, TypeScript, Node.js e sicurezza applicativa.