typescript - Typescript 中通用 Mixins 的解决方法
问题描述
我对 Typescript 比较陌生。似乎带有泛型的混合是一个问题,我很快就遇到了它。考虑以下示例:
(编辑:将提香的答案整合到方法 2 中并添加setValue()
以更好地说明新问题。)
class A<T> {
public constructor(public a: T) {}
public setValue(a: T): void {this.a = a;}
}
class B<T> extends A<T> {public constructor(public a: T, public b: T) {super(a);}}
// approach 1
function mixinC(Base: ???) { // ??? = typeof A vs. ??? = typeof B vs. ??? = any
return class CMixin<T> extends Base<T> {}; //...
}
// approach 2
type Constructor<T> = new (...args: any[]) => T;
function mixinC<T extends Constructor<A<unknown>>>(Base: T) {
return class CMixin extends Base {}; //...
}
// test 1
class C<T> extends mixinC(A)<T> {}
interface C<T> extends A<T> {}
const c = new C<string>('123');
c.setValue(7); // no error, although 7 is not string
console.log(c.a);
// test 2
class D<T> extends mixinC(B)<T> {}
interface D<T> extends B<T> {}
const d = new D<string>('465', '789');
console.log(d.a, d.b);
我希望这两种测试都有效,但两种方法都不起作用。
如果有一种方法可以动态地告诉编译器Base
将会是typeof A
or typeof B
,那么第一种方法会起作用(我认为),但mixinC<T>(Base: typeof T)
由于 T 是一种类型而不是值,所以它不起作用。我也尝试过any
作为类型;这似乎在表面上工作,但我可以访问C
(例如c.xyz
)的每个实例上的任意、未定义的属性。
第二种方法原则上与ES6 Mixin 在 TypeScript 中具有泛型类型非常相似,但主要区别在于A
(与BaseClass
那里相比)这里是泛型类型。那我应该换什么???和?如果我可以??? = A<T2>
使用参数类型T2
,也许它会起作用,但我应该在哪里定义这个参数?
@编辑:c.setValue(7);
可能不会引发错误,因为现在实际上共存了两个版本setValue
:string
一个(正确的)和unknown
一个,后者允许7
.
解决方案
我不确定为什么Constructor<any>
允许您访问任何属性,我实际上会将其归类为 Typescript 错误。使用{}
instead 似乎可以防止这种不良行为,并且还可以将泛型参数从目标类转发到生成的混合类:
class A<T> {public constructor(public a: T) {}}
class B<T> extends A<T> {public constructor(public a: T, public b: T) {super(a);}}
type Constructor<T> = new (...args: any[]) => T;
function mixinC<T extends Constructor<A<unknown>>>(Base: T) {
return class CMixin extends Base {
test() {
this.a
}
}; //...
}
// test 1
class C<T> extends mixinC(A)<T> {}
const c = new C<string>('123');
console.log(c.a);
c.xyzqqq // error
// test 2
class D<T> extends mixinC(B)<T> {}
const d = new D<string>('465', '789');
console.log(d.a, d.b);
推荐阅读
- java - 单击主按钮时Android显示按钮
- javascript - 根据正则表达式,我在发送时用 Keyup 事件捕获的数值没有正确写入内部输入
- python - 如何结合动画功能使用matplotlib按钮?
- excel - VBA msgbox 是/否 然后做点什么
- bash - 如何解析“whereis”输出以获取 Linux 中所需的路径?
- jquery - 如何将坐标对从字符串转换为谷歌地图多边形的数组?
- c - 如果是指针,是否可以将 _Generic 的控制表达式提升为数组类型?
- firebase - Firebase 部署的反应应用程序无法正常工作。未捕获的语法错误:意外的标记“<”
- c++ - 是否有返回写入缓冲区的字符数的 itoa 版本?
- python - 将浮点数组转换为枕头