Existe um `valueof` semelhante ao `keyof` no TypeScript? Otimização e desempenho
\n\nVocê já escreveu em TypeScript e se pegou pensando: "Eu tenho keyof para chaves, mas onde está o valueof para valores?" Se sim — você não está sozinho. Esta pergunta no Stack Overflow acumulou milhares de visualizações, e hoje vamos analisá-la do início ao fim. Mas não como uma teoria abstrata, e sim com foco em otimização e desempenho do seu código. Vamos nessa!
Por que `keyof` existe e `valueof` não?
\n\nNo TypeScript, existe o tipo utilitário embutido keyof. Ele pega um tipo de objeto e retorna a união de todas as suas chaves:
type Person = {\n name: string;\n age: number;\n isActive: boolean;\n};\n\ntype PersonKeys = keyof Person; // "name" | "age" | "isActive"\n\nE quanto aos valores? Gostaríamos de obter string | number | boolean do mesmo tipo. Na biblioteca padrão do TypeScript, isso não existe. Por quê? Porque valueof não é simplesmente uma "operação inversa". Um objeto pode ter muitas chaves com os mesmos tipos, e precisamos decidir como unificá-los. Mas isso não significa que não possamos escrever nosso próprio valueof!
Criando nosso próprio `ValueOf`
\n\nA maneira mais simples é usar o tipo de acesso por índice (indexed access type) em combinação com keyof:
type ValueOf<T> = T[keyof T];\n\ntype PersonValues = ValueOf<Person>; // string | number | boolean\n\nPronto! Acabamos de criar um tipo genérico ValueOf que funciona como valueof. Mas vamos mais fundo — como isso afeta o desempenho e como usar com sabedoria.
Otimização: quando `ValueOf` evita duplicação
\n\nImagine que você tem um objeto de configuração com dezenas de campos. Você quer escrever uma função que aceite qualquer valor desse objeto. Sem ValueOf, você teria que listar os tipos manualmente:
type Config = {\n apiUrl: string;\n timeout: number;\n retries: number;\n debug: boolean;\n};\n\n// Ruim: duplicação de tipos\nfunction setConfigValue(key: string, value: string | number | boolean) {\n // ...\n}\n\nAgora com ValueOf:
// Bom: captura automaticamente todos os tipos de valores\nfunction setConfigValue(key: keyof Config, value: ValueOf<Config>) {\n // TypeScript sabe que value só pode ser string | number | boolean\n}\n\nIsso não apenas reduz o código, mas também o torna autodocumentável. Se você adicionar um novo campo em Config, o TypeScript capturará o novo tipo automaticamente. Menos erros — mais produtividade no desenvolvimento.
`ValueOf` avançado com tipos condicionais
\n\nÀs vezes, precisamos obter valores apenas de chaves específicas. Por exemplo, todos os valores numéricos. É aí que entram os tipos condicionais (conditional types):
\n\ntype NumericValues<T> = {\n [K in keyof T]: T[K] extends number ? T[K] : never;\n}[keyof T];\n\ntype ConfigNumeric = NumericValues<Config>; // number (timeout | retries)\n\nEssa técnica é especialmente útil ao trabalhar com tipos grandes: você pode filtrar apenas os valores necessários e evitar verificações desnecessárias em tempo de execução. Otimização no nível de tipos é desempenho gratuito, porque os tipos desaparecem na compilação.
\n\nDesempenho em tempo de execução: é necessário?
\n\nUm ponto importante: ValueOf é uma construção puramente de tipo. Ela não gera nenhum código JavaScript. Mas seu uso correto pode indiretamente melhorar o desempenho da sua aplicação:
- \n
- Menos bugs — menos tempo de depuração. \n
- Tipagem mais rigorosa — o compilador detecta