我有以下服务
@Injectable()
export class CollectionService<T> {
constructor(protected http: Http) {}
factory<T>(item?: any): T {
let type: new (item?: any) => T;
return new type(item);
}
item(id): Observable<T> {
return this.http.get(`${this.baseUrl}/${id}`)
.map((resp: Response)=> this.factory(resp.json()))
.catch((error: any) => {
return Observable.throw(error);
});
}
}
编译成功通过,但我在浏览器控制台中有以下错误
TypeError: type is not a constructor
at PortalVideoService.webpackJsonp.../../../../../src/app/services/collection/collection.service.ts.CollectionService.factory (http://localhost:4200/main.bundle.js:1568:16)
at http://localhost:4200/main.bundle.js:1580:64
at Array.map (native)
at MapSubscriber.project (http://localhost:4200/main.bundle.js:1580:29)
at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (http://localhost:4200/vendor.bundle.js:24034:35)
at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (http://localhost:4200/vendor.bundle.js:13455:18)
at XMLHttpRequest.onLoad (http://localhost:4200/vendor.bundle.js:101703:38)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.bundle.js:2838:31)
at Object.onInvokeTask (http://localhost:4200/vendor.bundle.js:93420:37)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.bundle.js:2837:36)
如何创建T类型的对象?
答案 0 :(得分:6)
名称T
仅在编译时存在。您可以将它用于类型检查,但除非您有权访问构造函数,否则无法构造类型为T的对象。
更改factory
的定义以将运行时类型构造函数作为参数:
factory<T>(type: {new(): T}, item?: any): T {
return new type(item);
}
现在唯一的问题是找出你得到类型参数的地方;您可能还需要将其传递给item()
方法,以便编译器知道要生成Observable<T>
的类型。
答案 1 :(得分:1)
没有必要做你正在做的事情,只需做
.map((resp: Response)=> resp.json())
如果您想要响应的自定义类型
.map((resp: Response)=> resp.json() as CustomResponse)
其中CustomResponse
是一个接口。
答案 2 :(得分:0)
您可以将构造函数作为类泛型传递,而不是方法。
export class CollectionService<T, CT extends { new(item?: any): T }> {
constructor(protected http: Http, private type: CT) {}
factory(item?: any): T {
return new this.type(item);
}
// ...
}
class CustomClass {
constructor(private item?: any) {
}
};
let cs = new CollectionService<CustomClass, { new(): CustomClass }>(http, CustomClass);
console.dir(cs.factory(123));
// UPDATE
class CustomClassService extends CollectionService<CustomClass, { new(): CustomClass }> {
constructor(protected http: Http) {
super(http, CustomClass);
}
}
let ccs = new CustomClassService(http);
console.dir(ccs.factory(456));