[英]Pass a generic class type as a parameter of a generic function
I'm using a converter (external library) that has a method fromJson like the one below. 我正在使用具有来自Json的方法的转换器(外部库),如下所示。 I want to build a generic RESTService, but i don't know how to pass the generic class type to the method. 我想构建一个通用的RESTService,但是我不知道如何将通用的类类型传递给该方法。
// 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, ???)));
}
...
}
You can use t.constructor
as the Clazz<T>
argument. 您可以将t.constructor
用作t.constructor
Clazz<T>
参数。 You'll need to tell TypeScript it is of the right type using as
: 您需要使用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 , but as always, you should test it out in your own environment. 这似乎可以在TypeScript Playground中进行编译和工作 ,但是与往常一样,您应该在自己的环境中对其进行测试。
I did alter fromJson
just so that I could get a loggable result, and obviously testIt
is not exactly the same as your (Angular?) function, but hopefully it gets you going in the right direction. 我做了一些改变,只是为了让fromJson
可以得到可记录的结果,并且显然testIt
与您的(Angular?)函数并不完全相同,但是希望它可以使您朝正确的方向前进。
The library you are using is very bad and has semantic errors. 您使用的库非常糟糕,并且存在语义错误。 new
is a keyword used to initialize an instance of a class type. new
是用于初始化类类型的实例的关键字。 The return type is should always be consistent with this class type. 返回类型应始终与此类类型一致。 The correct definition should be: 正确的定义应为:
export declare type Clazz<T> = { new (...args: any[]): Clazz<T>; };
Solve this problem. 解决这个问题。 You can always use the keyword as
and Object.create(null)
to convert most object types to avoid compiler checking: 您始终可以使用关键字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)
give you a js object without any method binding --- a pure struct space. Object.create(null)
为您提供一个没有任何方法绑定的js对象-纯结构空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.