Skip to content

convertToUnderscore

描述

递归将所有小驼峰方式的属性名替换为下划线命名。该函数深度遍历对象和数组,将所有属性名从驼峰命名转换为下划线命名,常用于向后端 API 发送数据时的格式转换。

语法

ts
convertToUnderscore<T = any>(data: T): T

参数

  • data (T): 需要转换的数据,可以是对象、数组或原始值

返回值

  • T: 转换后的数据,保持原始数据结构不变

转换规则

函数会将属性名中的大写字母转换为下划线加小写字母的格式:

  • userNameuser_name
  • emailAddressemail_address
  • createdAtcreated_at

示例

基本对象转换

ts
import { convertToUnderscore } from '@fu/matrix';

const formData = {
  userName: 'John',
  emailAddress: 'john@example.com',
  createdAt: '2023-01-01'
};

const result = convertToUnderscore(formData);
console.log(result);
// => { user_name: 'John', email_address: 'john@example.com', created_at: '2023-01-01' }

数组转换

ts
import { convertToUnderscore } from '@fu/matrix';

const userList = [
  { userId: 1, userName: 'Alice' },
  { userId: 2, userName: 'Bob' }
];

const result = convertToUnderscore(userList);
console.log(result);
// => [{ user_id: 1, user_name: 'Alice' }, { user_id: 2, user_name: 'Bob' }]

嵌套对象转换

ts
import { convertToUnderscore } from '@fu/matrix';

const complexData = {
  userInfo: {
    basicInfo: {
      firstName: 'John',
      lastName: 'Doe'
    },
    contactList: [
      { phoneNumber: '123-456-7890' }
    ]
  }
};

const result = convertToUnderscore(complexData);
console.log(result);
// => {
//   user_info: {
//     basic_info: {
//       first_name: 'John',
//       last_name: 'Doe'
//     },
//     contact_list: [
//       { phone_number: '123-456-7890' }
//     ]
//   }
// }

API 请求数据处理

ts
import { convertToUnderscore } from '@fu/matrix';

// 发送 API 请求数据
async function createUser(userData) {
  // 转换为后端期望的下划线格式
  const apiPayload = convertToUnderscore(userData);
  
  const response = await fetch('/api/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(apiPayload)
  });
  
  return response.json();
}

// 使用示例
const user = await createUser({
  firstName: 'John',
  lastName: 'Doe',
  emailAddress: 'john@example.com'
});

表单数据处理

ts
import { convertToUnderscore } from '@fu/matrix';

function handleFormSubmit(formData) {
  // 前端表单数据(驼峰格式)
  const clientData = {
    firstName: formData.get('firstName'),
    lastName: formData.get('lastName'),
    emailAddress: formData.get('emailAddress'),
    phoneNumber: formData.get('phoneNumber'),
    preferences: {
      receiveEmails: formData.get('receiveEmails') === 'true',
      receiveNotifications: formData.get('receiveNotifications') === 'true'
    }
  };

  // 转换为 API 格式
  const apiData = convertToUnderscore(clientData);
  
  return submitToAPI(apiData);
}

数据库操作

ts
import { convertToUnderscore } from '@fu/matrix';

// ORM 查询构建
function buildQuery(conditions) {
  const dbConditions = convertToUnderscore(conditions);
  
  return db.users.where(dbConditions);
}

// 使用示例
const users = await buildQuery({
  firstName: 'John',
  isActive: true,
  createdAt: { $gte: new Date('2023-01-01') }
});

配置对象转换

ts
import { convertToUnderscore } from '@fu/matrix';

const clientConfig = {
  databaseUrl: 'mongodb://localhost:27017',
  maxConnections: 10,
  retryAttempts: 3,
  timeoutSettings: {
    connectionTimeout: 5000,
    queryTimeout: 30000
  }
};

const serverConfig = convertToUnderscore(clientConfig);
console.log(serverConfig);
// => {
//   database_url: 'mongodb://localhost:27017',
//   max_connections: 10,
//   retry_attempts: 3,
//   timeout_settings: {
//     connection_timeout: 5000,
//     query_timeout: 30000
//   }
// }

处理规则详解

属性名转换

  • 驼峰转下划线: userNameuser_name
  • 多个大写字母: userProfileImageURLuser_profile_image_u_r_l
  • 保持已有下划线: user_nameuser_name(不变)
  • 以下划线开头: _privateField_private_field

数据类型处理

  • 对象: 递归转换所有属性名
  • 数组: 递归转换数组中的每个元素
  • 原始值: 直接返回(字符串、数字、布尔值等)
  • 特殊值: nullundefinedDate 等保持不变

深度遍历

函数会递归处理所有嵌套的对象和数组,确保整个数据结构的一致性。

使用场景

  • API 请求数据: 将前端 camelCase 数据转换为后端 snake_case
  • 数据库操作: 转换查询条件和插入数据的格式
  • 配置文件生成: 生成服务器端配置文件
  • 第三方库集成: 适配不同库的数据格式要求

性能说明

  • 时间复杂度: O(n) - 其中 n 是所有属性和值的总数
  • 空间复杂度: O(n) - 创建新的数据结构
  • 不可变性: 不修改原始数据,返回新对象

注意事项

  • 函数会创建新的对象,不修改原始数据
  • 只转换对象的属性名,不转换属性值
  • 对于已经是下划线命名的属性,保持不变
  • 原始值(非对象/数组)会直接返回
  • 连续的大写字母会被逐个转换:XMLHttpRequestx_m_l_http_request

常见用法模式

与 convertToCamelCase 配合使用

ts
import { convertToCamelCase, convertToUnderscore } from '@fu/matrix';

// API 数据处理工具
class ApiClient {
  async get(url) {
    const response = await fetch(url);
    const data = await response.json();
    // 转换响应数据为驼峰格式
    return convertToCamelCase(data);
  }
  
  async post(url, data) {
    // 转换请求数据为下划线格式
    const payload = convertToUnderscore(data);
    const response = await fetch(url, {
      method: 'POST',
      body: JSON.stringify(payload)
    });
    const result = await response.json();
    // 转换响应数据为驼峰格式
    return convertToCamelCase(result);
  }
}

中间件集成

ts
import { convertToUnderscore } from '@fu/matrix';

// Express 中间件
function formatRequestData(req, res, next) {
  if (req.body) {
    req.body = convertToUnderscore(req.body);
  }
  next();
}

// 使用中间件
app.use(express.json());
app.use(formatRequestData);

相关方法

版本历史

  • v1.4.0: 初始版本