You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript 5.0.2中转换JSON对象键后能否实现类型安全?

解决方案:TypeScript 对象键转换并保留类型安全

要实现对象键从短横线命名到下划线命名的转换,同时保证类型安全,需要同时处理类型层面的键映射和运行时的转换逻辑,确保两者完全对齐。

1. 定义类型转换工具

首先创建字符串转换的类型工具,将短横线格式的字符串转为下划线格式:

type KebabToSnake<S extends string> = 
  S extends `${infer Prefix}-${infer Suffix}` 
    ? `${Prefix}_${KebabToSnake<Suffix>}` 
    : S;

接着用映射类型,把原对象的所有键应用上述转换,同时保留对应的值类型:

type TransformKeys<T> = {
  [K in keyof T as KebabToSnake<K & string>]: T[K];
};

2. 修正transform函数实现

调整函数的类型注解,让输入为原类型T,输出为转换后的TransformKeys<T>,同时修复运行时的遍历逻辑:

// 5.0.2 TypeScript Version
type InputType = {
  'first-name': string;
  'last-name': number; // 新增测试字段验证多键转换
};

type KebabToSnake<S extends string> = 
  S extends `${infer Prefix}-${infer Suffix}` 
    ? `${Prefix}_${KebabToSnake<Suffix>}` 
    : S;

type TransformKeys<T> = {
  [K in keyof T as KebabToSnake<K & string>]: T[K];
};

function transform<T extends object>(input: T): TransformKeys<T> {
  const result = {} as TransformKeys<T>;
  // 修复遍历逻辑:先获取对象的键数组,再逐个处理
  for (const key of Object.keys(input) as Array<keyof T>) {
    const parsedKey = key.replace(/\-/g, '_') as keyof TransformKeys<T>;
    result[parsedKey] = input[key];
  }
  return result;
}

const before = { 'first-name': 'Fernando', 'last-name': 28 };
const after = transform(before);

// 类型正确,可正常使用
after['first_name']; // 类型为string
after['last_name'];  // 类型为number

// 原短横线键会触发类型错误,符合预期
// after['first-name']; // 类型报错:不存在该属性

关键说明

  • KebabToSnake:利用TypeScript模板字符串类型和递归逻辑,支持处理多个短横线的场景(比如'a-b-c'会转为'a_b_c')。
  • TransformKeys<T>:通过键重映射(as关键字),将原类型的每个键转换后作为新键,完整保留原属性的类型信息。
  • 函数实现中,通过类型断言确保键的类型安全,避免使用any破坏类型系统。

内容的提问来源于stack exchange,提问作者NandoMB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 12:17:30