我正试图找到一种合适而直接的方法来将一个复杂的对象映射成一个更简单的对象。
我想使用这样的东西:
interface TransferableResponse<T> {
toServiceResponse(): T;
}
export interface SimpleUserObject {
accessToken: string;
refreshToken: string;
expiresIn: number;
refreshTokenExpiresIn: number;
roleIds: number[];
}
export class ComplexUserObject implements TransferableResponse<SimpleUserObject> {
accessToken: string;
refreshToken: string;
expiresIn: number;
refreshTokenExpiresIn: number;
someRedundancy: Guid;
someWeirdStuff: string;
complexRoles: [{id: number, name: string}];
constructor(init?: Partial<ComplexUserObject>) {
Object.assign(this, init);
}
toServiceResponse(): SimpleUserObject {
return {
...this,
roleIds: this.complexRoles.map(role => role.id)
};
}
}
在这种情况下,我创建的是ComplexUserObject
但是,当调用toServiceResponse()
时,我希望得到的只能是SimpleUserObject
中指定的属性。在现实中,我得到两者的组合(roleIds
,但也complexRoles
,someWeiredStuff
和someRedundancy
)。
长话短说,有一个简单的,一行的方式说...this
,但消除的东西不包括在一个类型?伪代码:(...this as SimpleUserObject)
不幸的是,您总是需要手动指定您希望以某种方式应用于SimpleUserObject
的ComplexUserObject
中的密钥。
运行时接口不存在,所以当接口被剥离时,您的代码需要是有效的JavaScript。JavaScript没有办法告诉方法"取这个键的子集"。没有在某个地方显式地列出这些键,例如,手动将这些键作为新对象的键,作为迭代的数组,作为迭代的引用对象等
最简单的方法就是列出新的键
toServiceResponse(): SimpleUserObject {
return {
accessToken: this.accessToken,
refreshToken: this.refreshToken,
expiresIn: this.expiresIn,
refreshTokenExpiresIn: this.refreshTokenExpiresIn,
roleIds: this.complexRoles.map(role => role.id)
};
}
您也可以使用类而不是接口(即使在JavaScript中也允许结果的具体实例成为类型化实体),但是仍然需要手工列出实例化类的键,只是这一次是在构造函数中,而不是直接在返回的对象
上export class SimpleUserClass {
constructor(public args: SimpleUserObject) {}
}
toServiceResponse(): SimpleUserClass {
return new SimpleUserClass({
accessToken: this.accessToken,
refreshToken: this.refreshToken,
expiresIn: this.expiresIn,
refreshTokenExpiresIn: this.refreshTokenExpiresIn,
roleIds: this.complexRoles.map(role => role.id)
})
}