如何实现TypeScript函数根据入参类型返回对应完整或Partial类型?
TypeScript实现驼峰转蛇形函数的动态类型返回
问题场景
现有一个将驼峰命名对象转换为蛇形命名对象的函数,当前实现只能接收Partial<CamelData>类型入参并返回Partial<SnakeData>类型,但需求是:
- 当入参为完整的
CamelData类型时,返回完整的SnakeData类型 - 当入参为
Partial<CamelData>类型时,返回Partial<SnakeData>类型
解决方案
方案1:函数重载(固定类型场景)
通过函数重载声明不同入参对应的返回类型,实现部分兼容两种情况:
// 原类型定义 interface CamelData { exempleId: number; myData: string; } interface SnakeData { exemple_id: number; my_data: string; } // 重载声明:明确入参类型与返回类型的对应关系 export function camelToSnake(camelData: CamelData): SnakeData; export function camelToSnake(camelData: Partial<CamelData>): Partial<SnakeData>; // 函数实现 export function camelToSnake( camelData: Partial<CamelData> ): Partial<SnakeData> | SnakeData { return { exemple_id: camelData.exempleId, my_data: camelData.myData }; }
使用时TypeScript会自动根据入参类型推断返回类型:
// 入参为完整CamelData,返回类型为SnakeData const fullData: CamelData = { exempleId: 1, myData: "test" }; const fullResult = camelToSnake(fullData); // fullResult类型为SnakeData // 入参为Partial<CamelData>,返回类型为Partial<SnakeData> const partialData: Partial<CamelData> = { exempleId: 2 }; const partialResult = camelToSnake(partialData); // partialResult类型为Partial<SnakeData>
方案2:泛型+条件类型(通用扩展场景)
如果需要支持更多类型转换,或者不想手动维护蛇形类型定义,可以用类型工具自动推导,并通过泛型条件类型实现动态返回:
// 驼峰转蛇形的字符串类型工具 type CamelToSnakeCase<S extends string> = S extends `${infer T}${infer U}` ? U extends Capitalize<U> ? `${Lowercase<T>}_${CamelToSnakeCase<Lowercase<U>>}` : `${T}${CamelToSnakeCase<U>}` : S; // 将对象所有键转为蛇形的类型工具 type CamelToSnakeObject<T> = { [K in keyof T as CamelToSnakeCase<string & K>]: T[K]; }; // 原驼峰类型 interface CamelData { exempleId: number; myData: string; } // 自动推导蛇形类型,无需手动定义 type SnakeData = CamelToSnakeObject<CamelData>; // 泛型函数:根据入参类型动态返回对应转换后的类型 export function camelToSnake<T extends Partial<CamelData>>( camelData: T ): T extends CamelData ? SnakeData : Partial<SnakeData> { const result: Record<string, unknown> = {}; // 通用驼峰转蛇形逻辑 for (const key in camelData) { const snakeKey = key.replace(/([A-Z])/g, "_$1").toLowerCase(); result[snakeKey] = camelData[key]; } return result as ReturnType<typeof camelToSnake<T>>; }
这个方案的优势是无需手动维护重载和蛇形类型定义,新增字段或类型时只需修改原驼峰类型即可自动适配。
内容的提问来源于stack exchange,提问作者RouckyKM
相关产品推荐
相关产品推荐

