FNSP Web Page

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 existe

3. 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.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.