实战小技巧:下划线转驼峰篇

前言

在日常的开发需求中,经常会碰到协作方的变量命名风格与我们自己项目中的变量命名风格不一致的情况。例如后端返回的变量命名是下划线,而前端使用的变量命名是驼峰。本文介绍了一种实用的方法将对象中的变量名由下划线转为驼峰,包括Typescript类型定义的转换,如果你有兴趣的话简单花5分钟学习一下吧~

对象命名转换

字符串转换

可以使用lodash的工具函数进行下划线/驼峰字符串之间的互转:

perl 复制代码
_.snakeCase('Foo Bar');
// => 'foo_bar'
 
_.snakeCase('fooBar');
// => 'foo_bar'
 
_.snakeCase('--FOO-BAR--');
// => 'foo_bar'

_.camelCase('Foo Bar');
// => 'fooBar'
 
_.camelCase('--foo-bar--');
// => 'fooBar'
 
_.camelCase('__FOO_BAR__');
// => 'fooBar'

工具函数🔧

typescript 复制代码
function transformObjectKeys<T extends Record<string, any>, K>(
  input: T,
  keyTransformer: (key: string) => string
): K {
  // 确保输入是对象
  if (input && typeof input === 'object' && !Array.isArray(input)) {
    const result: Record<string, any> = {};

    for (const key of Object.keys(input)) {
      const transformedKey = keyTransformer(key); // 使用转换函数生成新键
      const value = input[key];

      // 递归处理嵌套对象
      if (value && typeof value === 'object' && !Array.isArray(value)) {
        result[transformedKey] = transformObjectKeys(value, keyTransformer);
      } else {
        result[transformedKey] = value;
      }
    }

    return result as K;
  }

  // 如果不是对象,直接返回原始输入
  return input as unknown as K;
}


function formatApiResponse<T, K>(
  response: T,
  keyTransformer: (key?: string) => string = camelCase,
  deepClone = true
): K {
  const input = deepClone ? cloneDeep(response) : response;
  return transformObjectKeys(input, keyTransformer);
}

function formatApiRequest<T, K>(
  requestData: T,
  keyTransformer: (key?: string) => string = snakeCase,
  deepClone = false
): K {
  const input = deepClone ? cloneDeep(requestData) : requestData;
  return transformObjectKeys(input, keyTransformer) as K;
}

使用示例:

typescript 复制代码
const formattedResponse = formatApiResponse(apiResponse);
const apiResponse = { first_name: "John"};

// 调用 formatApiResponse 
const formattedResponse = formatApiResponse(apiResponse); console.log(formattedResponse);
// { firstName: "John"}

类型命名转换

除了可以将对象的成员变量命名进行下划线/驼峰互转之外,typescript类型也可以进行转换。 关于类型体操的前置学习文档,有兴趣可以看一下:

www.typescriptlang.org/docs/handbo... www.typescriptlang.org/docs/handbo...

下划线转驼峰

typescript 复制代码
// 将 Snake_Case 转换为 PascalCase
type SnakeToPascalCase<T extends string> = 
  T extends `${infer Head}_${infer Tail}`
    ? `${Capitalize<Head>}${SnakeToPascalCase<Tail>}`
    : Capitalize<T>;

// 将 Snake_Case 转换为 camelCase
type SnakeToCamelCase<T extends string> = 
  T extends `${infer Head}_${infer Tail}`
    ? `${Lowercase<Head>}${SnakeToPascalCase<Tail>}`
    : T;
    
// 将对象中的键从 Snake_Case 转为 camelCase,并递归处理子对象或数组
type SnakeToCamelCasedData<T> = T extends Array<infer U>
  ? SnakeToCamelCasedData<U>[]
  : T extends object
  ? {
      [K in keyof T as SnakeToCamelCase<Extract<K, string>>]: SnakeToCamelCasedData<T[K]>;
    }
  : T;

使用示例:

typescript 复制代码
interface SnakeCaseData {
  user_name: string;
  user_age: number;
}

// 将类型转换为 camelCase
type CamelCasedData = SnakeToCamelCasedData<SnakeCaseData>;

// 转换后的类型
type CamelCasedData = {
  userName: string;
  userAge: number;
};

驼峰转下划线

typescript 复制代码
// 将 camelCase 转换为 snake_case
type CamelToSnakeCase<T extends string> = T extends `${infer Char}${infer Rest}`
  ? `${Char extends Uppercase<Char> ? `_${Lowercase<Char>}` : Char}${CamelToSnakeCase<Rest>}`
  : T;

// 将对象中的键从 camelCase 转换为 snake_case,并递归处理子对象或数组
export type CamelToSnakeCasedData<T> = 
  T extends (...args: any[]) => any // 如果是函数类型,直接返回原类型
    ? T
    : T extends Array<infer U> // 如果是数组,递归处理每个元素
    ? CamelToSnakeCasedData<U>[]
    : T extends object // 如果是对象,递归处理每个键和值
    ? {
        [K in keyof T as CamelToSnakeCase<Extract<K, string>>]: CamelToSnakeCasedData<T[K]>;
      }
    : T; // 如果是基础类型,直接返回原类型

使用示例:

typescript 复制代码
interface CamelCaseData {
  userName: string;
  userAge: number;
}

// 将类型转换为 snakeCase
type SnakeCasedData = CamelToSnakeCasedData<CamelCaseData>;

// 转换后的类型
type SnakeCasedData = {
  user_name: string;
  user_age: number;
};
相关推荐
dualven_in_csdn2 小时前
搞了两天的win7批处理脚本问题
java·linux·前端
你的人类朋友2 小时前
✍️【Node.js程序员】的数据库【索引优化】指南
前端·javascript·后端
小超爱编程3 小时前
纯前端做图片压缩
开发语言·前端·javascript
应巅3 小时前
echarts 数据大屏(无UI设计 极简洁版)
前端·ui·echarts
Jimmy4 小时前
CSS 实现描边文字效果
前端·css·html
islandzzzz4 小时前
HMTL+CSS+JS-新手小白循序渐进案例入门
前端·javascript·css·html
Senar4 小时前
网页中如何判断用户是否处于闲置状态
前端·javascript
很甜的西瓜4 小时前
typescript软渲染实现类似canvas的2d矢量图形引擎
前端·javascript·typescript·图形渲染·canvas
Allen Bright5 小时前
【CSS-9】深入理解CSS字体图标:原理、优势与最佳实践
前端·css
阿芯爱编程6 小时前
最长和谐子序列,滑动窗口
前端·javascript·面试