簡體   English   中英

為什么實現接口的TypeScript類不能分配給擴展接口的通用約束?

[英]Why is this TypeScript class implementing the interface not assignable to a generic constraint extending the interface?

我正在嘗試為線性代數函數開發一些接口,因為世界需要另一個線性代數庫。 (可能很糟糕)的想法是能夠為某些更高級別的函數指定VectorMatrix ,並且只要尺寸正確,它就可以正常工作。

我在使用Vector接口執行此操作時遇到了一些問題,但是我發現將this用作一種類型並解決了我的問題(也許我在這里做得不好)。 我嘗試在Matrix界面中執行此操作,但是由於函數的參數不是Matrix類型,因此this技巧不起作用。

對於許多類似的功能,我也遇到了同樣的錯誤,但這是一個示例:

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接口的類型。

為什么我不能以這種方式做事? 我不明白此消息試圖告訴我什么。 我知道我可能可以解決此問題,但我也想更多地了解正在發生的事情,也許還可以學習(!)。

我正在使用TypeScript 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM