为什么这个实现接口的 TypeScript 类不能分配给扩展接口的泛型约束?



我正在尝试为线性代数函数开发一些接口,因为世界需要另一个线性代数库。(可能是坏的(想法是能够为一些更高级别的功能指定VectorMatrix,并让它正常工作,只要维度正确。

我在使用Vector接口时遇到了一些问题,但我发现使用this作为一种类型,它解决了我的问题(也许我在这里做了一件坏事(。我尝试在Matrix接口中执行此操作,但由于函数的参数不是类型Matrixthis技巧不起作用。

对于很多这样的函数,我都遇到了同样的错误,但这是一个例子:

interface Vector {
set (...args: number[]): this;
setScalar (scalar: number): this;
clamp (min: this, max: this): this;
...
}
class Vector2 implements Vector { ... }
interface Matrix {
elements: number[];
getRow<T extends Vector> (n: number): T;
...
}
class Matrix2 implements Matrix {
private _elements: number[];
public getRow (i: number): Vector2 {
const te = this._elements;
switch (i) {
case 0:
return new Vector2(te[0], te[2]);
case 1:
return new Vector2(te[1], te[3]);
default:
throw new Error('No row defined at ' + i + '.');
}
}
}

以这种方式构造接口,我收到以下错误消息:

Property 'getRow' in type 'Matrix2' is not assignable to the same property in base type 'Matrix'.
Type '(i: number) => Vector2' is not assignable to type '<T extends Vector>(n: number) => T'.
Type 'Vector2' is not assignable to type 'T'.ts(2416)

Vector2 实现 Vector 接口,getRow()上的泛型类型约束要求返回类型是实现 Vector 接口的类型。

为什么我不能这样做事?我不明白这条消息想告诉我什么。我知道我可能会解决这个问题,但我也想更多地了解正在发生的事情,也许可以学习(!(一些东西。

我正在使用打字稿 3.6.3。

我认为这里的问题是可以在调用站点指定通用T,但无论调用站点为T指定什么,m.getRow总是返回一个Vector2

例如,以下内容将是有效的 TypeScript,但在您的情况下不起作用。为了防止这种情况发生,TypeScript 不会编译并抛出错误。

class Vector3 extends Vector { }
const m = new Matrix()
const row = m.getRow<Vector3>(0) // You specify a Vector3, but get a Vector2.

这里最简单的解决方案是删除泛型并声明getRow始终返回Vector

interface Matrix {
elements: number[];
getRow(n: number): Vector;
}

最新更新