字符串类型工具
字符串类型工具提供了强大的类型级字符串操作功能,实现诸如将驼峰命名转换为蛇形命名等转换。
大小写转换
Camel2SnakeCase
将驼峰命名字符串转换为蛇形命名格式,可选择是否使用大写。
type Camel2SnakeCase<T extends string, U extends boolean = true> = /* ... */
// 示例
type Result1 = Camel2SnakeCase<'userName'>; // 'USER_NAME'
type Result2 = Camel2SnakeCase<'userId'>; // 'USER_ID'
type Result3 = Camel2SnakeCase<'myVariableName'>; // 'MY_VARIABLE_NAME'
// 使用小写选项
type Result4 = Camel2SnakeCase<'userName', false>; // 'user_name'
type Result5 = Camel2SnakeCase<'userId', false>; // 'user_id'
type Result6 = Camel2SnakeCase<'myVariableName', false>; // 'my_variable_name'
类型参数:
T extends string- 要转换的驼峰命名字符串U extends boolean = true- 是否使用大写(默认:true)
返回值:
- 蛇形命名格式的字符串类型
实际应用示例
API 请求/响应映射
import type { Camel2SnakeCase } from 'typescript-api-pro';
interface UserRequest {
firstName: string;
lastName: string;
emailAddress: string;
phoneNumber: string;
}
// 将所有属性名转换为大写蛇形命名用于 API
type ApiUserRequest = {
[K in keyof UserRequest as Camel2SnakeCase<K & string>]: UserRequest[K]
};
// 结果:
// {
// FIRST_NAME: string;
// LAST_NAME: string;
// EMAIL_ADDRESS: string;
// PHONE_NUMBER: string;
// }
// 使用示例
const apiPayload: ApiUserRequest = {
FIRST_NAME: 'John',
LAST_NAME: 'Doe',
EMAIL_ADDRESS: 'john@example.com',
PHONE_NUMBER: '+1234567890'
};
数据库列名映射
import type { Camel2SnakeCase } from 'typescript-api-pro';
interface UserModel {
userId: number;
userName: string;
createdAt: Date;
updatedAt: Date;
isActive: boolean;
}
// 转换为小写蛇形命名用于数据库列名
type DbUserColumns = {
[K in keyof UserModel as Camel2SnakeCase<K & string, false>]: UserModel[K]
};
// 结果:
// {
// user_id: number;
// user_name: string;
// created_at: Date;
// updated_at: Date;
// is_active: boolean;
// }
// 查询构建器示例
function buildQuery<T extends Record<string, unknown>>(
tableName: string,
data: T
): string {
const columns = Object.keys(data).join(', ');
const values = Object.values(data).map(v => `'${v}'`).join(', ');
return `INSERT INTO ${tableName} (${columns}) VALUES (${values})`;
}
const userData: DbUserColumns = {
user_id: 1,
user_name: 'johndoe',
created_at: new Date(),
updated_at: new Date(),
is_active: true
};
const query = buildQuery('users', userData);
环境变量命名
import type { Camel2SnakeCase } from 'typescript-api-pro';
interface AppConfig {
databaseUrl: string;
apiKey: string;
maxConnections: number;
enableLogging: boolean;
redisHost: string;
}
// 转换为大写蛇形命名用于环境变量
type EnvVars = {
[K in keyof AppConfig as Camel2SnakeCase<K & string>]: string
};
// 结果:
// {
// DATABASE_URL: string;
// API_KEY: string;
// MAX_CONNECTIONS: string;
// ENABLE_LOGGING: string;
// REDIS_HOST: string;
// }
// 环境变量加载器
function loadEnv<T extends Record<string, unknown>>(
keys: Array<keyof T>
): T {
const result: Record<string, string> = {};
for (const key of keys) {
const envKey = String(key);
result[envKey] = process.env[envKey] || '';
}
return result as T;
}
const env = loadEnv<EnvVars>([
'DATABASE_URL',
'API_KEY',
'MAX_CONNECTIONS',
'ENABLE_LOGGING',
'REDIS_HOST'
]);
GraphQL 模式生成
import type { Camel2SnakeCase } from 'typescript-api-pro';
interface Product {
productId: string;
productName: string;
productPrice: number;
productCategory: string;
}
// 生成 GraphQL 字段名(小写蛇形命名)
type GraphQLProduct = {
[K in keyof Product as Camel2SnakeCase<K & string, false>]: Product[K]
};
// 结果:
// {
// product_id: string;
// product_name: string;
// product_price: number;
// product_category: string;
// }
const graphqlType = `
type Product {
product_id: String!
product_name: String!
product_price: Float!
product_category: String!
}
`;
表单字段名称转换
import type { Camel2SnakeCase } from 'typescript-api-pro';
interface FormData {
firstName: string;
lastName: string;
emailAddress: string;
phoneNumber: string;
companyName?: string;
}
// 转换为蛇形命名用于 HTML 表单字段名
type FormFieldNames = {
[K in keyof FormData as Camel2SnakeCase<K & string, false>]: FormData[K]
};
// 结果:
// {
// first_name: string;
// last_name: string;
// email_address: string;
// phone_number: string;
// company_name?: string;
// }
// 表单生成器
function generateFormFields<T extends Record<string, unknown>>(
data: T
): string {
return Object.entries(data)
.map(([key, value]) => {
return `<input name="${key}" value="${value || ''}" />`;
})
.join('\n');
}
const formData: FormFieldNames = {
first_name: 'John',
last_name: 'Doe',
email_address: 'john@example.com',
phone_number: '+1234567890',
company_name: 'Acme Inc'
};
const formHtml = generateFormFields(formData);
常量定义
import type { Camel2SnakeCase } from 'typescript-api-pro';
interface ErrorCodes {
notFound: number;
unauthorized: number;
badRequest: number;
internalError: number;
}
// 转换为大写蛇形命名用于常量
type ErrorConstants = {
[K in keyof ErrorCodes as Camel2SnakeCase<K & string>]: ErrorCodes[K]
};
// 结果:
// {
// NOT_FOUND: number;
// UNAUTHORIZED: number;
// BAD_REQUEST: number;
// INTERNAL_ERROR: number;
// }
const HTTP_STATUS: ErrorConstants = {
NOT_FOUND: 404,
UNAUTHORIZED: 401,
BAD_REQUEST: 400,
INTERNAL_ERROR: 500
};
// 代码中使用
function handleError(code: keyof ErrorConstants) {
return HTTP_STATUS[code];
}
const statusCode = handleError('NOT_FOUND'); // 404
配置文件键名
import type { Camel2SnakeCase } from 'typescript-api-pro';
interface ServerConfig {
serverHost: string;
serverPort: number;
maxUploadSize: number;
enableCors: boolean;
corsOrigin: string[];
}
// 转换为小写蛇形命名用于配置文件(YAML/TOML)
type ConfigFileKeys = {
[K in keyof ServerConfig as Camel2SnakeCase<K & string, false>]: ServerConfig[K]
};
// 结果:
// {
// server_host: string;
// server_port: number;
// max_upload_size: number;
// enable_cors: boolean;
// cors_origin: string[];
// }
// 配置文件内容
const config: ConfigFileKeys = {
server_host: '0.0.0.0',
server_port: 3000,
max_upload_size: 10485760, // 10MB
enable_cors: true,
cors_origin: ['http://localhost:3000', 'https://example.com']
};
// 生成 YAML
function toYaml(obj: Record<string, unknown>): string {
return Object.entries(obj)
.map(([key, value]) => {
if (Array.isArray(value)) {
return `${key}:\n${value.map(v => ` - ${v}`).join('\n')}`;
}
return `${key}: ${value}`;
})
.join('\n');
}
const yamlConfig = toYaml(config);
类型安全优势
编译时验证
import type { Camel2SnakeCase } from 'typescript-api-pro';
// 类型安全的键名转换
function transformKeys<T extends Record<string, unknown>>(
obj: T
): { [K in keyof T as Camel2SnakeCase<K & string, false>]: T[K] } {
const result: Record<string, unknown> = {};
for (const key in obj) {
// 运行时将驼峰命名转换为蛇形命名
const snakeKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
result[snakeKey] = obj[key];
}
return result as { [K in keyof T as Camel2SnakeCase<K & string, false>]: T[K] };
}
// 使用示例
const camelCaseData = {
firstName: 'John',
lastName: 'Doe',
emailAddress: 'john@example.com'
};
const snakeCaseData = transformKeys(camelCaseData);
// TypeScript 知道结果类型:
// {
// first_name: string;
// last_name: string;
// email_address: string;
// }
// 类型安全的访问
console.log(snakeCaseData.first_name); // 正确
// console.log(snakeCaseData.firstName); // 错误:属性 'firstName' 不存在
与其他工具集成
import type { Camel2SnakeCase, KeyOf, ValueOf } from 'typescript-api-pro';
interface User {
userId: number;
userName: string;
userEmail: string;
}
// 转换键名
type DbUser = {
[K in keyof User as Camel2SnakeCase<K & string, false>]: User[K]
};
// 获取所有可能的值
type DbUserValue = ValueOf<DbUser>; // number | string
// 获取所有键名
type DbUserKey = KeyOf<DbUser>; // 'user_id' | 'user_name' | 'user_email'
// 类型安全的查询构建器
function buildSelectQuery<T extends Record<string, unknown>>(
table: string,
columns: Array<keyof T>
): string {
return `SELECT ${columns.join(', ')} FROM ${table}`;
}
const query = buildSelectQuery<DbUser>('users', ['user_id', 'user_name']);
// 结果:"SELECT user_id, user_name FROM users"
实现细节
Camel2SnakeCase 类型使用递归条件类型来处理每个字符:
- Fmt 辅助函数:根据布尔标志将字符转换为大写或小写
- ToSnakeCase:递归处理字符串,在大写字母前添加下划线
- Camel2SnakeCase:如果存在前导下划线则将其删除,并应用转换
这提供了编译时类型转换,零运行时开销,确保整个应用程序的类型安全。