[英]'formDirective' is defined as an accessor in class 'ControlContainer', but is overridden here in 'ConnectArrayDirective' as an instance property
[英]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 方庫,因此您的解決方案可能僅限於以下選項:
似乎在某些情況下您無法禁用此錯誤。
“打字稿無法區分 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.