簡體   English   中英

TS2611:“foo”被定義為“A”類中的屬性,但在“B”中作為訪問器被覆蓋

[英]TS2611: 'foo' is defined as a property in class 'A', but is overridden here in 'B' as an accessor

我在 Angular 應用程序中遇到 Typescript 編譯錯誤。 以下是示例代碼和錯誤消息。

請你指導我抑制這個錯誤。 我認為這段代碼根據 Javascript 是正確的。

- error TS2611: 'foo' is defined as a property in class 'A', but is overridden here in 'B' as an accessor.
export class A {
  foo: string;
}

export class B extends A {
  f1;
  set foo(name) {
    this.f1 = name;
  }
  get foo() {
    return this.f1;
  }
}

編者注:在評論中, A類和B類都在第三方庫中。

錯誤消息是正確的,因為這里有一個微妙的錯誤。 在父類中定義屬性時,會自動為其每個子類創建該屬性。

因此,在您編寫的代碼中,如果您沒有為 B 類編寫: set/get foo(name) { ... }該類無論如何都會具有foo屬性,因為該屬性是在B的父類中聲明的 - A .

在您的代碼中,您實際上是在使用訪問器聲明來破壞A中聲明的foo屬性。

如果您想要求A的所有子類聲明自己的foo屬性(類似於接口),請嘗試:

export class A {
  abstract foo: string;
}

這是編程語言中的常見行為,當您從父級繼承時,您不能使用相同的變量/函數/訪問器名稱,直到您指定新的名稱覆蓋舊的名稱,但始終必須是相同的類型。 因此,在您的示例中,我們在父級中有變量,在子級中有訪問器。 您可以進行以下更改:

class A {
  _foo: string = "";
  set foo(name) {
    this._foo = name;
  }
  get foo() {
    return this._foo;
  }
}

export class B extends A {
  f1: any;
  set foo(name) {
    this.f1 = name;
  }
  get foo() {
    return this.f1;
  }
}

我相信有一些方法可以省略類型限制(如果必須的話),但我不知道怎么做,我認為這不是好方法(程序應該對讀者很清楚)。

另一種方法是創建一個abstract類,您可以使用它來擴展您的子類。 我使用一個interface ,然后是一個abstract ,然后在我的最終類中擴展它,就像使用訪問器(get/set)一樣。

interface中,您將定義您的屬性。 但是,如果您要使用訪問器(get/set),則需要創建一個abstract 我只會在您針對類存儲和檢索數據的數據類型類上執行此操作。

下面的示例可以在這里找到帶有接口、抽象、擴展的 Typescript 游樂場示例

interface IQuote {

    qty: number,
    rate: number | string,
    total ? : number | string
}

abstract class AQuote implements IQuote {
  abstract set qty(x: number);
  abstract get qty(): number;
  abstract set rate(x: number | string);
  abstract get rate(): number | string;
  abstract set total(x: number | string);
  abstract get total(): number | string


  protected abstract updateTotal(): void
  abstract getTotalNum(): number


}

class quote extends AQuote {

  constructor(obj: IQuote) {
    super()
    this.qty = obj.qty
    this.rate = obj.rate
  }

  set qty(v: number) {
    this._qty = v;
    this.updateTotal()
  }

  get qty() {
    return this._qty;

  }

  set rate(v: number | string) {
    this._rate = Number(v);
    this.updateTotal()
  }

  get rate() {
    return new Intl.NumberFormat('en-GB', {
      style: 'currency',
      currency: 'GBP'
    }).format(Number(this._rate))
  }

  set total(v: number | string) {
    this._total = Number(v);
  }

  get total(): number | string {
    return new Intl.NumberFormat('en-GB', {
      style: 'currency',
      currency: 'GBP'
    }).format(Number(this._total))
  }

  getTotalNum() {
    return Number(this._total)
  }

  protected updateTotal() {
    this.total = Number(this._rate) * Number(this._qty)
  }

  private _qty: number = 1;
  private _rate: number | string = 1;
  private _total ? : number | string = (Number(this._rate) * this._qty);

}



class QuoteArray extends Array < quote > {

  getTotals(): number {
    let totalFigure: number = 0
    this.forEach(o => {
      totalFigure = totalFigure + o.getTotalNum()
    });
    return totalFigure
  }

}

let arry: QuoteArray = new QuoteArray();

arry.push(new quote({
  qty: 2,
  rate: 5
}))

arry.push(new quote({
  qty: 3,
  rate: 5
}))
arry.push(new quote({
  qty: 3,
  rate: 5
}))
arry.push(new quote({
  qty: 3,
  rate: 5
}))
arry.push(new quote({
  qty: 3,
  rate: 5
}))




console.log(arry);


console.log(arry.getTotals())

上面的示例創建了一個引號數組,我可以像數組一樣操作它,但我還擴展了 Array 類型以提供名為getTotals()的方法,以便它打印出格式化的貨幣。

正如有人已經發布的那樣,這是 TS 4 中新強制執行的錯誤檢查(請參見此處

但是,由於您完全處理的是第 3 方庫,因此您的解決方案可能僅限於以下選項:

  1. 看看您是否可以將該第 3 方庫升級到與您的 typescript 版本兼容的更新版本
  2. 分叉該庫並進行修復(創建一個 PR 供作者審查)。 現在使用你的叉子而不是庫。
  3. 將 typescript 降級到此錯誤檢查是可選的版本

似乎在某些情況下您無法禁用此錯誤。

“打字稿無法區分 d.ts 中的屬性和訪問器”

您可以在以下位置關注討論: https ://github.com/microsoft/TypeScript/issues/41347

固定/合並 2022/05/31; 但尚未發布 [截至 typescript@4.7.4]

如果您確實確定您的實現是正確的,那么您可以通過將// @ts-nocheck行放在 ts 文件的頂部來禁用檢查。 打字稿文件中的@ts-nocheck

暫無
暫無

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

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