@tryvols
Front-End разработчик

Как исправить эту ошибку типизации?

Error:(17, 28) TS2322: Type 'number' is not assignable to type 'T'.
'number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'BuffValues'.


Я сделал решение таким - `case 'number': return this._numberStep(value) as T;`, но оно мне совершенно не нравится т.к. нарушает типизацию, есть ли лучший способ?

import { SequentialBuff } from './sequential-buff';
import { BuffSequence } from '../../../../types/buffs';
import { assertNever } from '../../../../../../utils/assert-never';

type BuffValues = number | boolean;

export abstract class UniformSequentialBuff<T extends BuffValues> extends SequentialBuff<T> {
    protected readonly _sequence: BuffSequence<BuffValues>;

    constructor(value: T, duration: number) {
        super(duration);
        this._mainValue = value;
        this._sequence = new Array(this._duration).fill(this._mainValue);
    }

    protected mutate(value?: T): T {
        switch (typeof value) {
            case 'boolean': return this._mainValue;
            case 'number': return this._numberStep(value);
            default: return assertNever('Forbidden type of the buff value!');
        }
    }

    private _numberStep(value?: number): number {
        if (typeof this._mainValue === 'number') {
            return value * this._mainValue;
        }
        assertNever('The buff value must be number!');
    }
}
  • Вопрос задан
  • 3522 просмотра
Решения вопроса 1
Robur
@Robur
Знаю больше чем это необходимо
Это решение не нарушает типизацию, а наоборот - вы точно знаете что в этом случае в T будет именно number и поэтому `return this._numberStep(value)` полностью валидно. А вот компилятор не знает, и вы ему таким образом даете подсказку.
Конечно лучше если он сам смог вы сузить T до number в этом случае, но тут придется немного помочь.

Возможно есть какая-то конструкция чтобы разрулить типы автоматически без as, но при беглом размышлении в готову ничего не приходит, да и будет это по сути то же самое (дать компилятору понять что тут все ок) только с гораздо большим количеством доп кода.

Пишите as и спите спокойно.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы