Необязательный универсальный тип

У меня есть следующий метод регистрации:

  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).

Есть ли способ добиться этого?

Ответы

Ответ 1

В соответствии с TypeScript 2.2 (вы можете попробовать его на TS Playground), вызов this.logData("GET", data)data типа T) становится this.logData<T, {}>("GET", data) поскольку this.logData<T, {}>("GET", data).

Перегрузка, предложенная Дэвидом Бохунеком, может быть применена, если вывод не выполняется с использованием версии TS, которую вы используете. Во всяком случае, убедитесь, что вторая подпись до объявления и затем определена, иначе она не будет участвовать в доступных перегрузках.

// 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
}

Ответ 3

Вы можете написать метод перегрузки следующим образом:

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 будет выведен