假设我想创建一个接口addable
,它使用方法__add__
来描述类,该方法将类的对象添加到同一类的另一个对象中。
我们还要说我想要一个独立的函数add
,它接受同一个类的两个addable
个对象并返回它们的总和。
我的第一个想法是在界面中使用this
类型:
interface addable<T> {
__add__: (this: T, other: T) => T;
}
然后我按如下方式实现我的课程:
class Point implements addable {
constructor(public x: number, public y: number) { }
__add__(other: Point) {
return new Point(this.x + other.x, this.y + other.y);
}
}
哪个失败了:
编辑:经过一些研究后我发现Class'Point'错误地实现了接口'addable'。
属性类型“添加”不兼容。输入'(other:Point)=&gt;点'不能分配给''(其他:这个)=&gt;这个'。
类型'Point'不能指定为'this'类型。
this
类型引用了this
对象,而不是this
对象的类。所以这次尝试注定要失败。
请参阅the example 1。
我的第二个尝试是使用带有this
伪参数的泛型:
interface addable<T> {
__add__: (this: T, other: T) => T;
}
上面指定的类定义适用于这种情况。但是,当我尝试定义独立add
:
const add = <T>(a1: addable<T>, a2: addable<T>) => a1.__add__(a2);
我明白了:
'addable'类型的'this'上下文不能赋值给方法 '这''类型'''。
有没有人知道如何实现所需的行为?
EDIT2:
界面
interface Addable<T> {
add: (this: Addable<T>, other: Addable<T>) => Addable<T>;
}
显然是我想要的。那么独立的功能就是
const add = <T>(a1: Addable<T>, a2: Addable<T>) => a1.add(a2)
但这个定义过于宽松。它实际上是对Addable
的任何两个实例进行类型检查,而不仅仅是同一类的实例
interface Addable<T> {
add: (this: Addable<T>, other: Addable<T>) => Addable<T>;
}
class Point implements Addable<Point> {
constructor(public x: number, public y: number) { }
add(other: Point) {
return new Point(this.x + other.x, this.y + other.y);
}
}
class Num implements Addable<Num> {
constructor(public number: number) { }
add(other: Num) {
return new Num(this.number + other.number);
}
}
const add = <T>(a1: Addable<T>, a2: Addable<T>) => a1.add(a2)
var p1 = new Point(1, 1);
var num1 = new Num(10);
const wrongAdded = p1.add(num1); // correctly fails
const wrongAdded2 = add(p1, num1); // typechecks! why???
推断的添加类型为<{}>
。这听起来不对,但我不熟悉打字稿足以声称有任何见解。
答案 0 :(得分:0)
这实现了你想要的......我完全删除了参数this
。如果需要,我会重命名它。这允许将一个点添加到另一个点,返回结果点...
interface Addable<T> {
add: (other: T) => T;
}
class Point implements Addable<Point> {
constructor(public x: number, public y: number) { }
add(other: Point) {
return new Point(this.x + other.x, this.y + other.y);
}
}
var p1 = new Point(1, 1);
var p2 = new Point(3, 3);
var added = p1.add(p2);
alert(added.x + ' ' + added.y);
注意:我在这里调整了名称以使它们与野外的TypeScript更加一致 - 因为我不希望其他程序员将你的约定复制/粘贴到生产中。如果您愿意,可以自由使用名称addable
和__add__
。)
答案 1 :(得分:0)
问题的最后一个版本几乎就在那里。我对泛型类型的约束使用了错误的语法。最终版本看起来像这样
interface Addable<T> {
add: (this: Addable<T>, other: Addable<T>) => Addable<T>;
}
class Point implements Addable<Point> {
constructor(public x: number, public y: number) { }
add(other: Point) {
return new Point(this.x + other.x, this.y + other.y);
}
}
class Num implements Addable<Num> {
constructor(public number: number) { }
add(other: Num) {
return new Num(this.number + other.number);
}
}
const add: <T extends Addable<T>>(a1: T, a2: T) => T = function (a1, a2) {
return a1.add(a2);
}
var p1 = new Point(1, 1);
var p2 = new Point(2, 2);
var num1 = new Num(10);
const added = p1.add(p2);
const added2 = add(p1, p2);
const wrongAdded = p1.add(num1); // Fails
const wrongAdded2 = add(p1, num1); // Fails