web-dev-qa-db-ja.com

Typescriptオプションのジェネリック型

次のロギング方法があります。

_  private logData<T, S>(operation: string, responseData: T, requestData?: S) {
    this.logger.log(operation + ' ' + this.url);
    if (requestData) {
      this.logger.log('SENT');
      this.logger.log(requestData);
    }
    this.logger.log('RECEIVED');
    this.logger.log(responseData);
    return responseData;
  }
_

requestDataはオプションです。logDataをメソッドに送信しない場合、Sタイプを指定することなくrequestDataを呼び出すことができます。 :this.logData<T, any>('GET', data)this.logData<T>('GET', data)を呼び出したい。これを達成する方法はありますか?

39
Marius

TypeScript 2.2(TS Playgroundで試すことができます)に従って、this.logData("GET", data)(タイプdataTで)を呼び出すと、this.logData<T, {}>("GET", data)として正常に推測されます。

David Bohunekによって提案されたオーバーロードは、使用するTSバージョンで推論が失敗した場合に適用できます。とにかく、2番目の署名が宣言されてから定義される前であることを確認してください。そうでない場合、利用可能なオーバーロードに参加しません。

// Declarations
private logData<T>(operation: string, responseData: T);
private logData<T, S>(operation: string, responseData: T, requestData?: S);
// Definition
private logData<T, S>(operation: string, responseData: T, requestData?: S) {
    // Body
}
10
FstTesla

TypeScript 2.3以降では、 汎用パラメーターのデフォルト を使用できます。

private logData<T, S = {}>(operation: string, responseData: T, requestData?: S) {
  // your implementation here
}
82
kimamula

次のようにオーバーロードメソッドを記述できます。

_private logData<T>(operation: string, responseData: T);
private logData<T, S>(operation: string, responseData: T, requestData?: S) {
    this.logger.log(operation + ' ' + this.url);
    if (requestData) {
        this.logger.log('SENT');
        this.logger.log(requestData);
    }
    this.logger.log('RECEIVED');
    this.logger.log(responseData);
    return responseData;
}
_

しかし、this.logData<T, any>('GET', data)と書く必要はなく、代わりにthis.logData('GET', data)と書くだけなので、本当に必要だとは思いません。 Tタイプが推測されます

1
David Bohunek