在构建复杂的类层次结构时,我遇到了一个令人困惑的问题,每个类都是从独立的ES6模块类文件导出的,其中涉及mixin。
下面是一个简单的例子来重现我的问题:
mixinA.ts文件:
type Constructor = new (...args: any[]) => {};
export default function addMixinA<TBase extends Constructor>(Base: TBase) {
return class MixedInA extends Base {
public prop1 = 1
}
}
classB.ts文件:
import addMixinA from "./mixinA"
class ClassB {
public prop2 = 2
}
let ClassB_WithMixin = addMixinA(ClassB)
export default ClassB_WithMixin
classC.ts文件:
import classB from "./classB"
class ClassC {
// 'classB' refers to a value, but is being used as a type here. Did you mean 'typeof classB'? ts(2749)
public classB_instance: classB
}
正如您在我添加到错误行上方的注解中所看到的,当使用从classA.ts导出时,在文件classC.ts中产生了一个错误。
我做错什么了吗?你能发现我的错误吗?
2条答案
按热度按时间4jb9z9bj1#
恭喜你的第一篇文章!
试试这个:
不能使用
classB
来注解字段,因为classB
不是类型,而是值。要使用此值的 type,需要typeof
运算符(type Foo = typeof classB
)。或者,执行以下操作:
这里的区别是,我们不是做赋值(
let ClassB_WithMixin = addMixinA(ClassB)
),而是做继承(class ClassB_WithMixin extends addMixinA(ClassB) {}
),这会产生一个真实的的类。TypeScript中的类都是类型 * 和 * 值。ghg1uchk2#
是的,如果TypeScript mixin能够解决粗糙的边缘,它将是有价值的。事实上,我认为我宁愿打破DRY原则,而不是引入这种混乱。
使用OP中的例子,addMixinA应该返回一个类,它 * 确实 * 返回了一个类,但是作为返回值,这个类被当作一个值,所以,与正常声明的类不同,你也不能直接将它作为一个类型使用。
当你在同一个文件中进行mixin并使用这个类时,一切都很好。但是,如果你想在一个文件中配置这个类,并将它导出到另一个文件中使用,就像“classB.ts”一样,你想使用这个类创建新的示例 * 并将属性定义为该类型,你必须做一些类似于-
太乱了,我不喜欢。