我正在使用一种转换器(外部库),该转换器的方法如下所述,来自
// From the library
export declare type Clazz<T> = {
new (...args: any[]): T;
};
// From the library
export class Converter {
...
public fromJson<T>(json: any, clazz: Clazz<T>): T { ... }
...
}
// ******************************************************
// My Service on my Angular app
class RESTService<T> {
...
public save(t: T): Observable<T> {
return this.httpClient.post('http://...', t)
.pipe(map(res => this.converter.fromJson(res, ???)));
}
...
}
答案 0 :(得分:0)
您可以将t.constructor
用作Clazz<T>
参数。您需要使用as
告诉TypeScript正确的类型:
// From the library
declare type Clazz <T> = {
new(...args: any[]): T;
};
// From the library
class Converter {
public fromJson<T>(json: any, clazz: Clazz<T>) { return new clazz(); }
}
class Test {
public testIt<T>(test: T) {
const converter = new Converter();
var o = converter.fromJson("{}", test.constructor as new (...args: any[]) => T);
return o;
}
}
class TestObj {
testProp: string = "hello";
}
var o = new TestObj();
var t = new Test();
var a = t.testIt(o);
console.log(JSON.stringify(a));
This seems to compile and work in the TypeScript Playground,但与往常一样,您应该在自己的环境中对其进行测试。
我确实更改了fromJson
以便获得可记录的结果,显然testIt
与您的(Angular?)函数并不完全相同,但希望它可以使您正确进行方向。
答案 1 :(得分:0)
您使用的库非常糟糕,并且存在语义错误。 new
是用于初始化类类型的实例的关键字。返回类型应始终与此类类型一致。正确的定义应为:
export declare type Clazz<T> = {
new (...args: any[]): Clazz<T>;
};
解决此问题。您始终可以使用关键字as
和Object.create(null)
来转换大多数对象类型,以避免编译器检查:
class RESTService<T> {
...
public save(t: T): Observable<T> {
let clazz = Object.create(null) as Clazz<T>;
// clazz.someValue = 'Hello world';
return this.httpClient.post('http://...', t)
.pipe(map(res => this.converter.fromJson(res, clazz)));
}
...
}
Object.create(null)
为您提供了一个没有任何方法绑定的js对象-纯结构空间。