Description
Lets say I have a class called AbstractClass
:
// animal.ts
export abstract class Animal {
public abstract talk(): String;
}
// cat.ts
import {Animal} from "./animal";
export class Cat extends Animal {
public talk(): String {
return "meow";
}
}
// dog.ts
import {Animal} from "./animal";
export class Dog extends Animal {
public talk(): String {
return "whoof whoof";
}
}
Now I have another module that has dependency on that class.
import {Animal} from "animal-module/animal";
// play-with-animal.ts
export class PlayWithAnimal {
private animal: Animal;
constructor(animal: Animal) {
this.animal = animal;
}
public makeAnimalTalk(): void {
console.log(this.animal.talk());
}
}
// animal.component.ts
import {PlayWithAnimal} from "play-with-animal-module/play-with-animal.ts"
import {Cat} from "animal-module/cat";
someFunction() {
let cat: Cat = new Cat();
let playWithAnimal: PlayWithAnimal = new PlayWithAnimal(cat);
// here I get error saying:
// TS2345: Argument of type 'Cat' is not assignable to parameter of type 'Animal'. 'Animal' is not a class derived from 'Animal'.
}
Here is how the folder structure is. I am using node
to resolve the modules.
- app
animal.component.ts
// app has dependency of animal-module
- node_modules
- animal-module
animal.ts
cat.ts
dog.ts
- play-with-animal-module
play-with-animal.ts
// talking-animal-module has dependency of animal-module
- node_modules
- animal-module
animal.ts
cat.ts
dog.ts
My finding so far is that, as in the dog.ts
or cat.ts
, I have imported the Animal
as import {Animal} from "./animal";
. Notice the relative path.
However in PlayWithAnimal
or AppComponent
the module is resolved using the node resolution. Somehow typescript thinks that they are separate classes (eventhough) they are same as they are being loaded from different file paths.
If I wrap Animal in a exports module 'SomeModule'
and update the code to use SomeModule.Animal
then it works fine even if I load the class from 2 different files. However if I do so then I lose ability to import multiple classes like import {Animal, SomeotherClass}
.
So my question is:
- Is this by design or its an issue?
- If this is by design then how are we meant to resolve the modular dependencies?
Thanks.