【发布时间】:2017-09-08 11:40:44
【问题描述】:
使用 Angular 和 TypeScript,我们可以使用泛型和所有编译优点来确保某种类型的安全性。但是如果我们使用例如 HTTP 服务,我们不会得到一个特定的对象,而只是解析 JSON。例如,我们有一些通用方法可以做到这一点:
public get<T>(relativeUrl: string): Promise<T> {
const completeUrlPromise = this.createCompleteUrl(relativeUrl);
const requestOptions = this.createRequestOptions(ContentType.ApplicationJson, true);
return completeUrlPromise.then(completeUrl => {
return this.processResponse<T>(this.http.get(completeUrl, requestOptions));
});
}
private processResponse<T>(response: Observable<Response>): Promise<T> {
const mappedResult = response.map(this.extractData);
const result = mappedResult.toPromise();
return result;
}
private extractData(res: Response): any {
let body;
if (!Array.isArray(res)) {
if (res.text()) {
body = res.json();
}
} else {
body = res;
}
if (!JsObjUtilities.isNullOrUndefined(body)) {
return body;
}
return {};
}
最终,泛型类型在这种情况下是无用的,因为我们只是得到 JSON。如果通用对象具有 JSON 中没有的方法或属性,它们就会丢失。 为了避免这种情况,我们添加了传递构造函数来真正创建对象的可能性:
private processResponse<T>(response: Observable<Response>, ctor: IParameterlessConstructor<T> | null = null): Promise<T> {
let mappedResult = response.map(this.extractData);
if (ctor) {
mappedResult = mappedResult.map(f => {
const newObj = JsObjFactory.create(f, ctor);
return newObj;
});
}
const result = mappedResult.toPromise();
return result;
}
JsObjFactory 看起来像这样:
export class JsObjFactory {
public static create<T>(source: any, ctorFn: IParameterlessConstructor<T>): T {
const result = new ctorFn();
this.mapDefinedProperties(source, result);
return result;
}
private static mapDefinedProperties<T>(source: Object, target: T): void {
const properties = Object.getOwnPropertyNames(target);
properties.forEach(propKey => {
if (source.hasOwnProperty(propKey)) {
target[propKey] = source[propKey];
}
});
}
}
这适用于浅层对象,但如果属性也是具有构造函数的复杂类型,则不起作用。由于运行时没有类型,我目前最好的办法是解析属性,检查类是否存在,然后创建它们。但这似乎非常容易出错和繁琐。
由于我一直很确定,我不是唯一遇到此问题的人,是否有解决方案或我不知道的 TypeScript/JavaScript 功能,这会有所帮助?
【问题讨论】:
-
How do I initialize a typescript object with a JSON object 的可能重复项(那里有一些很好的答案)
标签: javascript json typescript generics