I encounter a puzzling problem when composing a complexe class hierarchy, each class being exported from separate ES6-modules-like files, with mixins involved.
Here's a simplified exemple reproducing my problem:
File "mixinA.ts":
type Constructor = new (...args: any[]) => {};
export default function addMixinA<TBase extends Constructor>(Base: TBase) {
return class MixedInA extends Base {
public prop1 = 1
}
}
File "classB.ts":
import addMixinA from "./mixinA"
class ClassB {
public prop2 = 2
}
let ClassB_WithMixin = addMixinA(ClassB)
export default ClassB_WithMixin
File "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
}
As you can see in the comment I added above the faulting line, an error is produced in the file classC.ts when using the export from classA.ts.
Am I doing something wrong? Can you spot my error?
Congratulations on your first post!
Try this:
class ClassC {
public classB_instance: InstanceType<typeof classB> = new classB()
}
You cannot annotate a field by using classB
, because classB
is not a type. It's a value. To use the type of this value, the typeof
operator is needed (type Foo = typeof classB
).
Alternatively, do this:
class ClassB_WithMixin extends addMixinA(ClassB) {}
class ClassC {
public classB_instance: ClassB_WithMixin = new ClassB_WithMixin()
}
This difference here is that instead of doing assignment (let ClassB_WithMixin = addMixinA(ClassB)
), we're doing inheritance (class ClassB_WithMixin extends addMixinA(ClassB) {}
) which produces a real class. And classes in TypeScript are both types and values.