打字稿 1.4 中的联合类型是否可以用于声明 d3 样式 "chained" getter/setters?
Can union types in typescript 1.4 be used to declare d3-style "chained" getter/setters?
D3 等库中的常见模式是 "stackable getter/setters"。
例如(来自this example):
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
这里,charge
、linkDistance
和size
作为setter,每个return一个force对象的实例,这样他们就可以"chained".
但是,它们也可以通过不指定参数来用作 getter,例如:
var d = force.linkDistance()
如果在第一个代码块之后调用,d
的值现在将为 30
。
我想使用 typescript 1.4 的新联合类型功能来创建这样的可链接 getter/setters。例如,以下编译为正确的 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,但我不知道如何在打字稿中实现这样的接口!
所以我的问题是,在打字稿中调用它们时,是否可以编写这样的可链接 getters/setters 而无需强制转换?或者,是否可以创建一个实现接口 IA
的打字稿 class?
返回你实际创建新类型的联合类型O|number
var o2: O|number = o.a(3);
TypeScript 编译器无法在不强制转换的情况下理解您需要的确切类型。
实际上联合类型的引入主要是为了消除函数重载,它们只能(至少目前)与类型 casting/checking 一起使用。
对于您的示例,我能看到的唯一方法是使用 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();
is it possible to code such chainable getters/setters without requiring casts when they are used called in typescript? Alternately, is it possible to create a typescript class that implements the interface IA
是的。使用函数重载:
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
D3 等库中的常见模式是 "stackable getter/setters"。
例如(来自this example):
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
这里,charge
、linkDistance
和size
作为setter,每个return一个force对象的实例,这样他们就可以"chained".
但是,它们也可以通过不指定参数来用作 getter,例如:
var d = force.linkDistance()
如果在第一个代码块之后调用,d
的值现在将为 30
。
我想使用 typescript 1.4 的新联合类型功能来创建这样的可链接 getter/setters。例如,以下编译为正确的 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,但我不知道如何在打字稿中实现这样的接口!
所以我的问题是,在打字稿中调用它们时,是否可以编写这样的可链接 getters/setters 而无需强制转换?或者,是否可以创建一个实现接口 IA
的打字稿 class?
返回你实际创建新类型的联合类型O|number
var o2: O|number = o.a(3);
TypeScript 编译器无法在不强制转换的情况下理解您需要的确切类型。
实际上联合类型的引入主要是为了消除函数重载,它们只能(至少目前)与类型 casting/checking 一起使用。
对于您的示例,我能看到的唯一方法是使用 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();
is it possible to code such chainable getters/setters without requiring casts when they are used called in typescript? Alternately, is it possible to create a typescript class that implements the interface IA
是的。使用函数重载:
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