I cannot get inheritance to work across CommonJS modules generated using typescript 1.0 (tsc
is run using --module commonjs
)
This fails when two classes inheriting the same base class, call each other "through" the base class.
What seems to hapeen is that the first class imports the Base Class, which imports the second class which also imports the Base Class but the last Base Class import is failing.
An example illustrating this behaviour is provided below.
Is there anything in the Typescript or the CommonJS specifications preventing me from doing this, or is this a bug ?
=== Example ===
This fascinating piece of software is failed by running Lower.test.ts
. What it simply tries to achieve is loading a word into Lower
which keeps it in lower case, then using the inherited toUpper()
method from the Base
class, transforms it in upper case using the Upper
class (which also inherits Base
)
Lower.test.ts
import Lower = require('./Lower')
console.log(new Lower('smallcaps').toUpper())
Base.ts
import Upper = require('./Upper')
class Base {
word: string
toUpper(): string {
return new Upper(this.word).word
}
}
export = Base
Upper.ts
import Base = require('./Base')
class Upper extends Base {
constructor(word:string) {
super()
this.word = word.toUpperCase()
}
}
export = Upper
Lower.ts
import Base = require('./Base')
class Lower extends Base {
constructor(word:string) {
super()
this.word = word.toLowerCase()
}
}
export = Lower
After some research and testing, this ends up being a case of circular dependencies.
The issue is pretty well documented and various solutions have been proposed:
requiring
: hererequire
or using injection: hereUnfortunately, there is very little control on where
import
andexport
statements can be set in Typescript which reduces solutions to injection only. The rewrittenBase
class is provided below.Circular dependencies are a pain in Javascript modular projects. Typescript somehow makes things worse. That is bad news for a language supposed to address large projects
EDIT I have opened a case and submitted a proposed transpiler fix to the TypeScript project: here
Base.ts
Upper.ts
It is usually best to depend in just one direction - as per SOLID principles.
However, as you always need both
Base
andUpper
(i.e. you cannot have one without the other) you can add them to the same module...base.ts
lower.ts
app.ts