TypeScript将对象键从PascalCase递归转换为驼峰格式

我需要创建一个函数来将对象的键从 PascalCase 修改为 camelCase 格式。IE

const input = {
    FirstName: 'John',
    LastName: 'Smith'
};

const expectedOutput = {
    firstName: 'John',
    lastName: 'Smith'
};

// function looks as follows
function pascalToCamelCase<T>(input: T): CamelCaseKeys<T> {
    if (typeof input !== 'object' || input === null) {
        return input;
    }

    // do conversion....
    return output;
}

但我不知道如何通过 CamelCaseKeys 相应地修改密钥

回答

嗯,我今天学到了一些东西!我们可以使用新的 typescript 4.1 模板字符串文字功能和实用方法以类型安全的方式实现这一点。

Capitalize<T> 将大写一个字符串。

Uncapitalize<T> 将取消大写一个字符串(你所追求的)。

更多信息在这里。

从这两个我们可以构建一个辅助类型UncapitalizeObjectKeys<T>

type UncapitalizeKeys<T extends object> = Uncapitalize<keyof T & string>;

type UncapitalizeObjectKeys<T extends object> = {
  [key in UncapitalizeKeys<T>]: Capitalize<key> extends keyof T ? T[Capitalize<key>] : never;
}

笔记:

  • Uncapitalize<keyof T & string> - 我们与字符串相交只得到 T 的字符串键,因为我们不能将数字或符号大写
  • 我们必须将 in 的键取消大写[key in UncapitalizeKeys<T>],然后重新大写它们以实际从 T 中提取正确的值T[Capitalize<key>]。条件部分Capitalize<key> extends keyof T 只是检查大写的、未大写的键是否仍可分配给keyof T,因为 TS 无法维持这种关系(……还没有?)。

然后我们可以从@spender 的答案中提取几个部分 - 替换运行时类型检查,因为 TS 应该能够断言这些(假设这些对象不是来自 IO:

type UncapitalizeObjectKeys<T extends object> = {
  [key in UncapitalizeKeys<T>]: Capitalize<key> extends keyof T ? T[Capitalize<key>] : never;
}

type UncapitalizeKeys<T extends object> = Uncapitalize<keyof T & string>;


export const lowerCaseKeys = <T extends object>(obj: T): UncapitalizeObjectKeys<T> => {
    const entries = Object.entries(obj);
    const mappedEntries = entries.map(
        ([k, v]) => [
            `${k.substr(0, 1).toLowerCase()}${k.substr(1)}`,
            lowerCaseKeys(v)]
    );

    return Object.fromEntries(mappedEntries) as UncapitalizeObjectKeys<T>;
};

我们现在得到了我们想要的输出:

游乐场链接


以上是TypeScript将对象键从PascalCase递归转换为驼峰格式的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>