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
相关产品推荐
相关产品推荐

