網站搜尋

TypeScript:基於泛型的方法簽名


我有以下通用類別:

export class AClass<Data = void> {

refresh(data: Data): void {}

}

我希望 refresh 方法的簽名是:

refresh(){} // when Data = void
refresh(data: Data){} // otherwise

我不想讓資料參數變成可選的

refresh(data?: Data){} // not what I want because if data is different than "void" the arguments will be optional as well

我能做到的最好辦法是使用一個保存函數的變數,而不是使用方法。

export class AClass<Data = void> {
    refresh: Data extends void ? () => void : (data: Data) => void = (...arg){
        console.log(...arg);
    }
}

我懷疑我們是否可以在同一個類中定義條件方法(類)簽名,但這準確嗎?

[編輯] 為什麼有這個問題?

這是一個 TS 類別:

class Example {
  aMethod () {
    console.log(`I am a method`)
  };

  aVariable = () => {console.log(`I am a variable holding a function`)}
}

這將被轉譯成這個:

"use strict";
class Example {
    constructor() {
        this.aVariable = () => { console.log(`I am a variable holding a function`); };
    }
    aMethod() {
        console.log(`I am a method`);
    }
    ;
}

我們可以清楚地看到,雖然兩者最終都會達到相同的效果,但方法一更接近「原生」ES6 方法的實現。因此,我想找出是否有一種方式可以對類別的方法進行類型定義,這樣我仍然是在使用方法而不是變數。

答案#1

我沒有看到你的程式碼有任何問題:

class AClass<T = void> {
    refresh(data: T): void {
        console.log(data);
    }
}

const instance = new AClass();

instance.refresh(); // log: undefined
instance.refresh('test'); // Compiler error

const instance2 = new AClass<string>();

instance2.refresh(); // Compiler error
// log: compiler error if not present
instance2.refresh('compiler error if not present');

轉譯為:

"use strict";
class AClass {
    refresh(data) {
        console.log(data);
    }
}
const instance = new AClass();
instance.refresh();
const instance2 = new AClass();
instance2.refresh('test');