網站搜尋

javascript - 如何確保擴展的類在 TypeScript 中必須設置屬性值?


如果我有一個類別 foo:

class Foo {
  id: number
  name: string

  sayHi() {
    console.log('hi')
  }
}

我如何確保任何繼承自 foo 的類別必須為 id 和 name 設定值?

class Bar extends Foo {
  // must set these values
  id = 1
  name = 'bar'
}

這個概念或模式有名稱嗎?我不能把 Foo 當作介面,因為它必須有方法,讓繼承的類別可以使用。

答案#1

給 Foo 一個建構子,該建構子需要它們作為參數:

class Foo {
  constructor(public id: number, public name: string) {
    // Validate them here if desired
  }

  sayHi() {
    console.log('hi');
  }
}

由於子類別必須呼叫其父類別的建構子(隱式或顯式),如果嘗試呼叫時未傳入必要的參數,TypeScript 編譯器將會標示錯誤:Supplied parameters do not match any signature of call target. 例如,以下兩種情況都會失敗:

class Bar extends Foo {
}
const b = new Bar();   // Supplied parameters do not match any signature of call target.

和

class Bar extends Foo {
  constructor() {
    super();           // Supplied parameters do not match any signature of call target.
  }
}

注意那裡使用的有趣 TypeScript 功能:因為我們在建構函數的參數上給出了存取修飾符,當建構函數被呼叫時,實例屬性會自動被創建並設置為那些值。它相當於:

class Foo {
  id: number;
  name: string;

  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
    // Validate them here if desired
  }

  sayHi() {
    console.log('hi');
  }
}

(因為預設的修飾符是 public。)