TypeScript 4.5 更新:
随着tail recursion elimination on conditional types 的引入,现在可以编写Camelize 的版本,将键转换为驼峰式大小写,而不会像以前那样容易遇到递归深度限制:
CamelizeString<T, C> 类型使用C 作为累加器来存储将T 中的snake case 字符串转换为C 中的camel case 字符串的中间结果。
type CamelizeString<T extends PropertyKey, C extends string = ""> =
T extends string ? string extends T ? string :
T extends `${infer F}_${infer R}` ?
CamelizeString<Capitalize<R>, `${C}${F}`> : `${C}${T}` : T;
其余代码与以下版本相同。
Playground link to code
TypeScript 4.1 引入了template literal types 和key remapping in mapped types(见microsoft/TypeScript#40336),所以你可以这样实现:
type CamelizeString<T extends PropertyKey> =
T extends string ? string extends T ? string :
T extends `${infer F}_${infer R}` ? `${F}${Capitalize<CamelizeString<R>>}` : T : T;
type Camelize<T> = { [K in keyof T as CamelizeString<K>]: T[K] }
type CamelizeExample = Camelize<Example>;
/* type CamelizeExample = {
firstName: string;
lastName: string;
homeTown: string;
} */
const e: Camelize<Example> = {
firstName: 'string',
lastName: 'string',
homeTown: 'string'
}
CamelizeString<T> 的实现在字符串 T 中找到第一个下划线字符 ("_"),将其删除,并在对剩余部分递归调用 CamelizeString 后将字符串的剩余部分大写。并且Camelize<T> 将T 的每个键K 重新映射到CamelizeString<K>。
Playground link to code