【发布时间】:2017-01-23 16:51:27
【问题描述】:
假设我想创建一个接口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);
}
}
失败:
类“Point”错误地实现了接口“addable”。
属性“add”的类型不兼容。类型 '(other: Point) => Point' 不可分配给类型 '(other: this) => this'。
类型“Point”不可分配给类型“this”。
编辑:经过一些研究,我发现this 类型指的是this 对象,而不是this 对象的类。所以这次尝试注定要失败。
我的第二个想法是使用带有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' 上下文不可分配给方法的 'T' 类型的'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???
推断的添加类型是<{}>。这听起来不对,但我对打字稿的熟悉程度不足以要求任何见解。
【问题讨论】: