TypeScript:如何将多属性对象转换为少属性类型(从多到少)
解决TypeScript中类实例转换时多余属性的问题
问题根源
你遇到的问题其实是TypeScript编译时类型和运行时行为的差异导致的:Object.assign是运行时API,它会把源对象的所有可枚举属性都复制到目标对象,完全不会管TypeScript类里定义了哪些属性。而TypeScript的类型约束只在编译阶段生效,运行时你的B实例本质上还是一个普通对象,会带上A实例的所有属性。
几种简洁的解决方案
1. 手动赋值最直接(适合属性少的场景)
直接在构造函数里只提取需要的属性赋值,能确保运行时实例只有类定义的属性:
class B { public value1: string; public value2: string; constructor(item: A) { this.value1 = item.value1; this.value2 = item.value2; } } class C { public value3: string; public value4: string; public value5: string; constructor(item: A) { this.value3 = item.value3; this.value4 = item.value4; this.value5 = item.value5; } }
2. 解构赋值简化代码
用对象解构提取需要的属性,代码更简洁清爽:
class B { public value1: string; public value2: string; constructor({ value1, value2 }: A) { this.value1 = value1; this.value2 = value2; } } class C { public value3: string; public value4: string; public value5: string; constructor({ value3, value4, value5 }: A) { this.value3 = value3; this.value4 = value4; this.value5 = value5; } }
3. 工具函数复用提取逻辑(适合多类复用场景)
如果需要转换的类很多,可以写一个通用的pick工具函数,专门提取指定属性,避免重复代码:
// 通用属性提取工具函数 function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> { const result = {} as Pick<T, K>; keys.forEach(key => { result[key] = obj[key]; }); return result; } class B { public value1: string; public value2: string; constructor(item: A) { Object.assign(this, pick(item, ['value1', 'value2'])); } } class C { public value3: string; public value4: string; public value5: string; constructor(item: A) { Object.assign(this, pick(item, ['value3', 'value4', 'value5'])); } }
额外小提示
你的代码里有个小错误:let arr1: A = {"value1":"ONE",...}是单个A实例,不能直接用map方法。如果是数组的话应该写成:
let arr1: A[] = [{"value1":"ONE","value2":"TWO","value3":"THREE","value4":"FOUR","value5":"FIVE"}]; let arr2 = arr1.map(item => new B(item));
内容的提问来源于stack exchange,提问作者dmd
相关产品推荐
相关产品推荐

