Перегрузка обобщенных классов в машинописи - PullRequest
0 голосов
/ 01 декабря 2018

Я работаю против следующей проблемы, которую не могу решить (я упростил классы для этого поста).В конце концов я хочу указать различные запросы.У них есть определенная иерархия, которую я планирую моделировать с использованием наследования.В качестве отправной точки я создал абстрактный базовый класс:

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

Есть ли способ достичь этого, не определяя два разных класса имен?Причина, по которой я хочу попытаться избежать этого, потому что это переносится на производные классы (у всех классов в иерархии тоже будет две версии).

Заранее спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...