網站搜尋

Typescript 方法重載,用於不同類型的參數但相同的回應


我需要使用 TypeScript 來重載一個方法。

FooModel 有 6 個參數,但其中只有 2 個字串參數是必填的。所以我不想每次想使用 myMethod 時都創建一個 FooModel,我希望重載 myMethod,然後在那裡創建一次 FooModel,再執行其餘的邏輯後返回。

我已經根據目前在網上找到的資訊嘗試過這個,但我得到以下錯誤:

TS2394: This overload signature is not compatible with its implementation signature.

這個錯誤的解決方案與我的方法不相容

    static async myMethod(model: FooModel): Promise<BarResult>
    static async myMethod(inputText: string, outputText: string): Promise<BarResult>{
         //implementation;
      return new BarResult(); //Different content based on the inputs
    }

答案#1

問題

來自 TypeScript 的文件:

多載簽名與實作簽名

這是常見的困惑來源。人們經常會這樣寫程式碼,卻不明白為什麼會出錯:

function fn(x: string): void;
function fn() {
  // ...
}
// Expected to be able to call with zero arguments
fn();
^^^^
Expected 1 arguments, but got 0.

同樣, 用來撰寫函數主體的簽名無法從外部「看到」。

實作的簽名從外部不可見。在撰寫重載函數時,你應該總是在函數實作之上有兩個或更多的簽名。

實作簽名也必須與重載簽名相容。例如,這些函數有錯誤,因為實作簽名與重載的方式不正確:

function fn(x: boolean): void;
// Argument type isn't right
function fn(x: string): void;
         ^^
This overload signature is not compatible with its implementation signature.

function fn(x: boolean) {}
function fn(x: string): string;
// Return type isn't right
function fn(x: number): boolean;
         ^^
This overload signature is not compatible with its implementation signature.

function fn(x: string | number) {
  return "oops";
}

- TypeScript 關於重載和實現簽名的文件

在你的情況下,你定義了以下重載簽名:

static async myMethod(model: FooModel): Promise<BarResult>

但是實作簽名沒有重疊。你實作簽名中的第一個參數是 string,而重載是 FooModel;你實作簽名中的第二個參數是 string,而重載是 undefined。

static async myMethod(inputText: string, outputText: string): Promise<BarResult>{

解決方案

將你目前的實作簽名變成一個重載,並新增一個與你的兩個重載都相容的實作簽名:

class Foo {
  static async myMethod(model: FooModel): Promise<BarResult>;
  static async myMethod(inputText: string, outputText: string): Promise<BarResult>;
  static async myMethod(modelOrInputText: string | FooModel, outputText?: string): Promise<BarResult>{
   //implementation;
    return new BarResult(); //Different content based on the inputs
  }
}

- TypeScript 遊樂場