像D3这样的库中的常见模式是“可堆叠的getter / setter”。
例如(来自this example):
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
此处,charge
,linkDistance
和size
用作setter,每个setter都返回force对象的一个实例,以便它们可以“链接”。
但是,它们也可以通过不指定参数而用作吸气剂,例如:
var d = force.linkDistance()
如果在第一个代码块之后调用,则d
的值现在为30
。
我想使用typescript 1.4的新联合类型功能来创建这样的可链接的getter / setter。例如,以下内容编译为正确的javascript:
class O {
private _a: number = 0;
a(x: number = null): O|number {
if (x) {
this._a = x;
return this;
}
return this._a;
}
}
这样从javascript我可以做到:
var o = new O();
var v = o.a(3).a();
现在v = 3.
但是从打字稿中,我需要施放:
var o = new O();
var v: number = <number>(<O>o.a(3)).a();
不太吸引人!
有趣的是,看看d3.d.ts,似乎人们一直在创建具有正确签名的接口,如下所示:interface IA {
a: {
(): number;
(x: number): IA;
}
}
这在某种程度上神奇地解析为正确的签名来包装javascript,但我不知道如何在typescript中实现这样的接口!
所以我的问题是,是否可以编写这样的可链接的getter / setter而不需要在使用typescript中调用时使用强制转换?或者,是否可以创建实现接口IA
?
答案 0 :(得分:4)
是否有可能对这些可链接的getter / setter进行编码而不需要在使用typescript中调用时使用强制转换?或者,是否可以创建实现接口IA
的typescript类
是。使用函数重载:
interface IA {
a: {
(): number;
(x: number): IA;
}
}
class A implements IA {
private _a;
a(): number
a(x: number): A
a(x?: any): any {
if (x == void 0){
return this._a;
}
else {
this._a = x;
return this;
}
}
}
var foo = new A();
var bar = foo.a(123); // okay
console.log(bar.a()); // 123
foo.a('not a number'); // Error
答案 1 :(得分:1)
返回你实际创建新类型O|number
var o2: O|number = o.a(3);
TypeScript编译器无法在不进行强制转换的情况下理解您需要的确切类型。
实际上,引入的联合类型主要是为了删除函数重载,并且只能使用类型转换/检查来使用它们(至少现在)。
对于您的示例,我能看到的唯一方法是使用2种不同的方法来设置和获取值:
class O {
private _a: number = 0;
setA(x: number): O {
this._a = x;
return this;
}
getA(): number {
return this._a;
}
}
var o: O = new O();
var v: number = o.setA(3).getA();