Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
t para buscar uma tradução, passamos uma string com o caminho até a chave desejada. Se essa chave não existir, o erro só será percebido em tempo de execução, o que pode afetar a qualidade da entrega.
Por exemplo, imagine um dicionário assim:
const dict = {
footer: {
copyright: "Direitos reservados",
},
header: {
logo: "Logo da Empresa",
link: "Link do Header",
},
}.
Queremos que o TypeScript nos avise se tentarmos usar uma chave inexistente, como footer.logo, que não existe. Sem uma tipagem adequada, o compilador não consegue detectar esse erro.
type DeepKeys<T> = T extends object ? {
[K in keyof T]-?: `${K & string}` | `${K & string}.${DeepKeys<T[K]>}`
}[keyof T] : "". Sem esse critério, a solução pode parecer simples no começo e cara no suporte.
Este tipo recursivamente constrói uma união de todas as chaves possíveis, como 'footer', 'footer.copyright', 'header.logo', etc. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco.
function t<P extends DeepKeys<typeof dict>>(p: P): string {
// implementação fictícia
return ''. }
Assim, se tentarmos passar uma chave que não existe, o TypeScript emitirá erro de compilação. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois.
type AllKeys = DeepKeys<typeof dict>. // Agora, ao usar t, o editor sugere as chaves válidas Esse contexto ajuda a separar ganho real de novidade difícil de sutsentar. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco.
// Exemplo de uso:
const texto = t('footer.copyright'). // OK
const erro = t('footer.logo'). // Erro em tempo de compilação A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar.
t para validação de chaves.
3. Manter os dicionários bem estruturados e documentados.
4. Testar a integração com o TypeScript para evitar problemas de performance ou limites de recursão.
Essa abordagem melhora significativamente a confiabilidade do sistema de tradução, além de potencializar a experiência do desenvolvedor com autocompletar e validações em tempo de compilação. A adoção de tipos avançados, como template literals, foi um avanço recente no TypeScript, e usá-los nesse contexto é um exemplo de como aproveitar a evolução da linguagem para resolver problemas práticos. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta.
No meu time, usamos scripts que geram os tipos a partir dos arquivos de tradução. Assim, evitamos divergências e o TypeScript sempre está atualizado com o dicionário.
Acho que o maior desafio é mesmo manter o dicionário sincronizado com os tipos, principalmente em projetos grandes. E aí, alguma dica pra facilitar essa manutenção?
Concordo, o tipo ajuda na validação, mas às vezes o dicionário muda com frequência, né? Talvez usar ferramentas de validação automática ajude a evitar divergências.