Я работаю против следующей проблемы, которую не могу решить (я упростил классы для этого поста).В конце концов я хочу указать различные запросы.У них есть определенная иерархия, которую я планирую моделировать с использованием наследования.В качестве отправной точки я создал абстрактный базовый класс:
export abstract class RequestBase<TResult> {
public async execute(): Promise<TResult> {
const response = await this.transmit();
return this.getResult(response);
}
private async transmit(): Promise<any> {
// Code that transmits the requests, and yields a response, typed "any".
}
protected abstract getResult(response: any): TResult;
}
getResult
будет преобразовывать объект ответа в тип, определенный производным классом.Я планирую иметь больше абстрактных классов, например:
export abstract class RequestDerived<TResult> extends RequestBase<TResult> {
constructor() {
super(); // some parameterization suited for this request type.
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что меня не всегда интересует результат запросов.Это будет означать, что TResult
равно void
.В идеале я мог бы записать что-то вроде этого:
// A request that will convert the response to a number.
export class FirstRequest extends RequestDerived<number> {}
// A request for which we do not care about the result.
export class SecondRequest extends RequestDerived {}
Эта запись возможна, когда я задаю обобщенный констант в RequestDerived
как <TResult = void>
, но это все равно заставит меня реализовать getResult
в SecondRequest
, которая была бы просто фиктивной функцией.
Что концептуально нужно достичь, так это иметь реализацию getResult
для TResult = void
и иметь производные классы, специфичные для нее, когда TResult != void
.Что-то вроде:
export abstract class RequestDerived<TResult> extends
RequestBase<TResult> {
constructor() {
super();
}
}
// Note: No longer abstract - we know the implementation for TResult = void.
// Not allowed: [ts] Duplicate identifier 'RequestDerived'. [2300]
export class RequestDerived extends RequestDerived<void> {
constructor() {
super();
}
protected getResult(response: any): void {
return; // We don't care about the result!
}
}
Есть ли способ достичь этого, не определяя два разных класса имен?Причина, по которой я хочу попытаться избежать этого, потому что это переносится на производные классы (у всех классов в иерархии тоже будет две версии).
Заранее спасибо!