O satisfies, ou como validar sem perder o tipo
Há uma escolha que o TypeScript obrigava a fazer desde sempre: ou se anota o tipo de uma constante — e perde-se tudo o que ela tem de específico — ou não se anota nada, e ninguém verifica se está certa.
O satisfies, que chegou no TypeScript 4.9, acaba com a escolha: verifica o valor contra um tipo sem substituir aquilo que o TypeScript já sabia sobre ele.
1. O problema
type Cor = string | [number, number, number];
// Com anotação: fica validado, mas o TypeScript esquece o que cada cor é
const paletaAnotada: Record<string, Cor> = {
primaria: '#2e7d32',
fundo: [245, 245, 245],
};
paletaAnotada.primaria.toUpperCase();
// ~~~~~~~~~~~ Erro: 'toUpperCase' não existe em 'string | [number, number, number]'
paletaAnotada.inventada; // sem erro nenhum — qualquer chave serve// Sem anotação: os tipos são exatos, mas ninguém valida nada
const paletaSolta = {
primaria: '#2e7d32',
fundo: [245, 245, 245],
erro: 'vermelho-torrado-42', // ninguém se queixa
};2. A solução
const paleta = {
primaria: '#2e7d32',
fundo: [245, 245, 245],
} satisfies Record<string, Cor>;
paleta.primaria.toUpperCase(); // funciona: continua a ser string
paleta.fundo[0]; // funciona: continua a ser um tuplo de números
paleta.inventada;
// ~~~~~~~~~ Erro: a propriedade não existe3. Onde compensa mesmo
Em qualquer objeto de configuração com chaves conhecidas — rotas, definições, mapas de tradução:
const rotas = {
inicio: '/',
blog: '/blog',
contactos: '/contact',
} satisfies Record<string, `/${string}`>;
// O tipo das chaves continua a ser 'inicio' | 'blog' | 'contactos',
// e não um 'string' qualquer.
type NomeDeRota = keyof typeof rotas;A regra: : declara o que a coisa é, as mente sobre o que ela é, e satisfies confirma que ela cabe — sem alterar nada.