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

标签 typescript

我需要创建一个函数来将对象的键从 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 相应地修改 key

最佳答案

好吧,我今天学到了一些东西!我们可以使用新的 typescript 4.1 模板字符串文字功能和实用方法以类型安全的方式实现这一点。Capitalize<T>将大写一个字符串。Uncapitalize<T>将取消大写一个字符串(你所追求的)。
更多信息 here在这些上。
从这两个我们可以构建一个辅助类型 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 的字符串键,因为我们不能将数字或符号大写
  • 我们必须将 [key in UncapitalizeKeys<T>] 中的键取消大写- 然后用 T[Capitalize<key>] 将它们重新大写以实际从 T 中提取正确的值.条件部分Capitalize<key> extends keyof T 只是检查大写,未大写的 key 是否仍可分配给 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>;
    };
    
    
    我们现在得到了我们想要的输出:
    enter image description here
    游乐场link

    关于TypeScript 将对象键从 PascalCase 递归转换为驼峰格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65019600/

    相关文章:

    typescript - 如何在Electron项目中添加自己的 typescript 类

    javascript - Sequelize - 如何比较日期之间的相等性

    reactjs - React-Native/Typescript - 未定义不是一个对象(评估'react_1.default.Component)

    javascript - 主题不发出数据

    typescript - d.ts 中对 servicestack typescript 客户端的日期支持

    javascript - 如何将月份值从一个 Date 对象复制到另一个?

    typescript - TypeScript 规范中 AB|C 中的 AB 是什么意思?

    javascript - 如何在 Nest.js 中获取嵌套的 URL 查询

    javascript - 使用 cypress 读取 jsonArray 的内容

    不活动后 Angular 4 重定向