TypeScript オブジェクトキーガイド
TypeScript の Object Keys を camelCase に変換
snake_case API payload を camelCase object にする場合、runtime 変換と compile-time shape の両方を考える必要があります。
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>
}再帰 mapped type で string key と array element を表現し、呼び出し側に変換後の型を返せます。
type-level remapping は実データを変えないため、network payload には runtime function も必須です。
本番環境のエッジケース
- 複雑な略語規則では runtime と type-level の結果がずれる可能性があります。
- 型が正しく見えても key collision は runtime data の問題です。
- Symbol key や非 JSON class instance は明示的に扱います。
- _id や $schema 接頭辞を runtime で保持するなら正確な型が必要な場合は type 側にも例外を反映します。
オブジェクトキーをオンラインでテスト
JSON を貼り付けて、再帰変換、トップレベルのみ、除外キー、_/$ 接頭辞、衝突処理を確認できます。
.json ファイルをドロップ、または端末から選択
ファイルはブラウザ内でのみ読み取ります。最大 5 MB。
変換後 JSON
{
"userProfile": {
"firstName": "Ada",
"createdAt": "2026-09-12"
}
}解析、ファイル読み込み、整形、キー変換はすべてブラウザ内で実行されます。JSON 入力は変換サーバーへ送信されません。