Inheritance 跨CommonJS模块的Typescript继承-循环依赖
我无法使继承在使用typescript 1.0生成的CommonJS模块之间工作(Inheritance 跨CommonJS模块的Typescript继承-循环依赖,inheritance,typescript,commonjs,Inheritance,Typescript,Commonjs,我无法使继承在使用typescript 1.0生成的CommonJS模块之间工作(tsc使用--module CommonJS运行) 当继承同一基类的两个类“通过”基类相互调用时,这将失败 在hapeen看来,第一个类导入基类,第二个类导入基类,第二个类也导入基类,但最后一个基类导入失败 下面提供了一个说明这种行为的示例 Typescript或CommonJS规范中是否有任何东西阻止我这样做,或者这是一个bug? ==示例=== 运行Lower.test.ts,此迷人的软件失败。它试图实现的只是
tsc
使用--module CommonJS
运行)
当继承同一基类的两个类“通过”基类相互调用时,这将失败
在hapeen看来,第一个类导入基类,第二个类导入基类,第二个类也导入基类,但最后一个基类导入失败
下面提供了一个说明这种行为的示例
Typescript或CommonJS规范中是否有任何东西阻止我这样做,或者这是一个bug?
==示例===
运行Lower.test.ts
,此迷人的软件失败。它试图实现的只是将一个单词加载到Lower
中,并将其保留为小写,然后使用Base
类中继承的toUpper()
方法,使用upper
类(也继承Base
)将其转换为大写
下测试
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
//This import will "fail" by importing an empty object but is needed to trick the compiler
//An alternative is to design and Upper.d.ts definition file and reference it
import Upper = require('./Upper')
class Base {
//Upper is a sub-class of Base and needs to be injected to be instantiated
private _Upper: typeof Upper
word: string
constructor(_Upper: typeof Upper) {
this._Upper = _Upper
}
toUpper(): string {
//This where the injection is used
return new this._Upper(this.word).word
}
getUpperWord(upper: Upper): string {
//The injection is not reauired in this case
return upper.word
}
}
export = Base
上流社会
import Base = require('./Base')
class Upper extends Base {
constructor(word:string) {
super()
this.word = word.toUpperCase()
}
}
export = Upper
import Base = require('./Base')
class Upper extends Base {
constructor(word:string) {
super(Upper)
this.word = word.toUpperCase();
}
}
export = Upper
下塔台
import Base = require('./Base')
class Lower extends Base {
constructor(word:string) {
super()
this.word = word.toLowerCase()
}
}
export = Lower
通常最好只依赖一个方向——根据可靠的原则 但是,由于您始终需要
基础
和上部
(即,如果没有另一个,则不能有一个),因此您可以将它们添加到同一模块中
base.ts
export class Base {
word: string
toUpper(): string {
return new Upper(this.word).word
}
}
export class Upper extends Base {
constructor(word: string) {
super()
this.word = word.toUpperCase()
}
}
下塔台
import b = require('base')
class Lower extends b.Base {
constructor(word: string) {
super()
this.word = word.toLowerCase()
}
}
export = Lower
app.ts
import Lower = require('lower');
console.log(new Lower('smallcaps').toUpper());
经过一些研究和测试,这最终是一个循环依赖的情况 这一问题有很好的记录,并提出了各种解决方案:
要求
或使用注入:import
和export
语句的位置几乎没有控制,这使得解决方案只限于注入。下面提供了重写的Base
类
循环依赖是Javascript模块化项目中的一个难题。打字脚本让事情变得更糟。这对于一种用来处理大型项目的语言来说是个坏消息
编辑
我已经打开了一个案例,并向TypeScript项目提交了一个建议的transpiler修复程序:
Base.ts
import Upper = require('./Upper')
class Base {
word: string
toUpper(): string {
return new Upper(this.word).word
}
}
export = Base
//This import will "fail" by importing an empty object but is needed to trick the compiler
//An alternative is to design and Upper.d.ts definition file and reference it
import Upper = require('./Upper')
class Base {
//Upper is a sub-class of Base and needs to be injected to be instantiated
private _Upper: typeof Upper
word: string
constructor(_Upper: typeof Upper) {
this._Upper = _Upper
}
toUpper(): string {
//This where the injection is used
return new this._Upper(this.word).word
}
getUpperWord(upper: Upper): string {
//The injection is not reauired in this case
return upper.word
}
}
export = Base
上流社会
import Base = require('./Base')
class Upper extends Base {
constructor(word:string) {
super()
this.word = word.toUpperCase()
}
}
export = Upper
import Base = require('./Base')
class Upper extends Base {
constructor(word:string) {
super(Upper)
this.word = word.toUpperCase();
}
}
export = Upper
感谢您的解决方案;我可以接受这样一个事实,即它减少了模块化,但仍然留下了一个问题。至于朝一个方向走,它并不总是有意义的:想象一下这个非常简单的几何应用程序,它实现了一个
向量。一个向量
可以通过将它乘以另一个向量
来缩放,就像许多其他几何图形一样。创建一个Scalable
类是有意义的,该类由Vector
继承,并实现一个scale()
方法,该方法以Vector
作为参数。给你:继承一个在方法中使用它的一个子类的类。我仍然会避免它。如果一个向量总是可以伸缩的,为什么它是可伸缩的子类呢。如果它不能总是伸缩,它就不应该有scale方法,scale方法应该由可伸缩子类添加。