基于TypeScript实现按Schema复制并重命名对象属性的函数
TypeScript 对象转换函数:按Schema保留并重命名属性
要实现一个TypeScript函数,能根据给定的Schema对象将输入对象转换为新对象。Schema的核心作用是:
- 筛选属性:只保留Schema中声明的属性,未声明的直接忽略
- 重命名属性:为保留的属性指定新键名,支持嵌套对象的重命名(通过
_self字段指定当前嵌套对象的新键)
示例说明
输入对象
const input = { firstName: "Jane", lastName: "Miller", address: { street: "123 Fake Street", city: "Fake City", }, };
Schema对象
const schema = { firstName: "MyFirstName", address: { _self: "MyAddress", street: "MyStreet" } };
预期输出
const output = { MyFirstName: "Jane", MyAddress: { MyStreet: "123 Fake Street" } };
类型定义与函数实现
类型声明
先定义支持递归嵌套的Schema类型,以及自动推导输出结果的类型:
// Schema类型:支持直接重命名(字符串)或嵌套对象(含_self重命名自身) type Schema<T = unknown> = | string | ({ [K in keyof T]?: Schema<T[K]> } & { _self?: string }); // 自动推导转换后的输出类型 type Transformed<T, S> = S extends string ? { [K in S]: T } : S extends { _self: infer NewKey } ? { [K in NewKey]: Transformed<T, Omit<S, '_self'>> } : { [K in keyof S as S[K] extends string ? S[K] : never]: S[K] extends string ? T[K] : Transformed<T[K], S[K]> } & (S extends { _self: string } ? {} : { [K in keyof S as S[K] extends { _self: infer NK } ? NK : never]: S[K] extends { _self: any } ? Transformed<T[Extract<K, keyof T>], Omit<S[K], '_self'>> : never });
转换函数实现
采用递归方式处理嵌套对象,严格遵循Schema规则:
function transform<T, S extends Schema<T>>(input: T, schema: S): Transformed<T, S> { const result: Record<string, any> = {}; // 处理Schema为字符串的场景(直接将当前对象重命名为指定键) if (typeof schema === 'string') { return { [schema]: input } as Transformed<T, S>; } // 遍历Schema属性,跳过_self先处理子属性 for (const key in schema) { if (key === '_self') continue; const schemaRule = schema[key]; const inputValue = input?.[key as keyof T]; if (inputValue === undefined) continue; if (typeof schemaRule === 'string') { // 直接重命名属性 result[schemaRule] = inputValue; } else if (typeof schemaRule === 'object' && schemaRule !== null) { if ('_self' in schemaRule) { // 嵌套对象需重命名自身,先递归处理子属性 const nestedResult = transform(inputValue, schemaRule as Omit<typeof schemaRule, '_self'>); result[schemaRule._self] = nestedResult; } else { // 普通嵌套对象,直接递归处理 result[key] = transform(inputValue, schemaRule); } } } return result as Transformed<T, S>; }
测试验证
const input = { firstName: "Jane", lastName: "Miller", address: { street: "123 Fake Street", city: "Fake City", }, }; const schema = { firstName: "MyFirstName", address: { _self: "MyAddress", street: "MyStreet" } }; const output = transform(input, schema); console.log(output); // 输出结果与预期一致: // { MyFirstName: 'Jane', MyAddress: { MyStreet: '123 Fake Street' } }
内容的提问来源于stack exchange,提问作者yumba
相关产品推荐
相关产品推荐

