Guia de chaves de objeto em TypeScript

Converter chaves de objeto para camelCase em TypeScript

Apps TypeScript geralmente precisam da transformação runtime e de uma forma de tipo correspondente para payloads snake_case.

Por Equipe editorial do Camel Case ConverterPublicado em 12 de set. de 2026Última revisão

Implementação em TypeScript

type CamelCase<S extends string> =
  S extends `${infer Head}_${infer Tail}`
    ? `${Lowercase<Head>}${Capitalize<CamelCase<Tail>>}`
    : Uncapitalize<S>

type Camelize<T> =
  T extends readonly (infer Item)[] ? Camelize<Item>[] :
  T extends Record<string, unknown> ? { [K in keyof T as K extends string ? CamelCase<K> : K]: Camelize<T[K]> } : T

function toCamelKey(key: string) {
  return key.replace(/[-_]+([a-zA-Z0-9])/g, (_, char: string) => char.toUpperCase())
}

function keysToCamel<T>(value: T): Camelize<T> {
  if (Array.isArray(value)) return value.map(keysToCamel) as Camelize<T>
  if (value === null || typeof value !== "object") return value as Camelize<T>
  const output: Record<string, unknown> = {}
  for (const [key, child] of Object.entries(value)) {
    const nextKey = toCamelKey(key)
    if (Object.hasOwn(output, nextKey)) throw new Error(`Key collision: ${nextKey}`)
    output[nextKey] = keysToCamel(child)
  }
  return output as Camelize<T>
}

Um mapped type recursivo pode descrever chaves renomeadas e preservar estruturas de array.

O tipo não transforma dados de rede; a função runtime continua obrigatória.

Casos extremos em produção

  • Regras complexas de siglas podem fazer runtime e type-level divergir.
  • Colisões de chaves continuam sendo um problema de dados runtime.
  • Symbol keys e instâncias não JSON devem ser tratados explicitamente.
  • Se prefixos semânticos forem preservados em runtime, reflita as exceções nos tipos quando necessário.

Testar chaves de objeto online

Cole um objeto JSON para testar conversão recursiva, apenas nível superior, exclusões, prefixos _/$ e colisões.

Solte um arquivo .json ou escolha no dispositivo

Arquivos são lidos apenas no navegador. Tamanho máximo: 5 MB.

JSON convertido
{
  "userProfile": {
    "firstName": "Ada",
    "createdAt": "2026-09-12"
  }
}

Parsing, leitura de arquivo, formatação e conversão rodam localmente no navegador. O JSON não é enviado a um servidor de conversão.