这个标题可能有误导性,但我真的不知道如何表达我的问题。
我想提供一个泛型类(或只是类体)作为函数参数。然后提供的类应该推断它的泛型。
class Builder<EXT, INT = EXT> {
// some builder stuff, which changes the generic T
withBar(): Builder<EXT, INT & { bar: string }> {
return this as any;
}
// here's the problem:
build(clazz: MyClass<INT>): MyClass<EXT> {
return wrap(clazz); // this method already exists and works
}
}
用途:
const builder = new Builder<{ foo: number }>();
// EXT = { foo: number }, INT = { foo: number }
builder = builder.withBar();
// EXT = { foo: number }, INT = { foo: number, bar: string }
builder.build(class { /* here I should be able to access this.foo and this.bar */ });
// Here I just want to provide the class body,
// because I don't want to type all the generics again.
// I don't want to specify `MyClass<?>`,
// because the correct type is already specified within the Builder
作为一个(丑陋的)“变通方法”,我找到了一种方法,分别提供所有类方法,然后从中构建一个类。像这样:
class Builder<EXT, INT = EXT> {
build(args: {method1?: any, method2?: any}): MyClass<EXT> {
class Tmp {
method1() {
return args.method1 && args.method1(this);
}
method2(i: number) {
return args.method2 && args.method2(this);
}
}
return wrap(Tmp);
}
}
但那真的很难看。
基本上,我只是想给
build
方法。然后这个方法将从中创建一个类,调用
wrap
然后返回。
有什么办法吗?
编辑:另一个尝试解释我的问题:
现在我必须使用这样的代码:
builder.build(class extends AbstractClass<{ foo: number, bar: string }> {
private prop: string;
init() {
this.prop = this.data.foo // provided by AbstractClass
? 'foo'
: 'bar'
}
getResult() {
return {
foo: this.prop,
bar: this.data.bar // provided by AbstractClass
}
}
})
如你所见,我必须详细说明
AbstractClass
. 我不想指定类型,因为
builder
已经知道类型了。
我只想提供类的主体,而不需要再次指定泛型类型。像这样:
builder.build(class extends AbstractClass<infer the type with magic!> {
...
getResult() {
return { this.data.foo }
}
})
或者:
builder.build(class {
...
getResult() {
return { this.data.foo }
}
})