Проверка времени выполнения, что переключатель является исчерпывающим (когда это время компиляции исчерпывающее) - PullRequest
1 голос
/ 30 мая 2019

У меня есть оператор switch, который охватывает все возможности времени компиляции, но, поскольку значение может быть предоставлено пользователем, я хочу обрабатывать неожиданные значения во время выполнения.

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

Упрощенный пример :

type Circle = { shape: "circle", radius: number };
type Rectangle = { shape: "rectangle", length: number, width: number };

function area(shape: Circle | Rectangle): number {
    switch (shape.shape) {
        case "circle": return Math.PI * shape.radius * shape.radius;
        case "rectangle": return shape.length * shape.width;
    }
    throw new Error(`Unexpected shape '${shape.shape}'`); // Error: Property 'shape' does not exist on type 'never'.
}

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

1 Ответ

1 голос
/ 30 мая 2019

эта страница предлагает решение: https://www.typescriptlang.org/docs/handbook/advanced-types.html

Адаптировано для вашего примера:


    type Circle = { shape: "circle", radius: number };
    type Rectangle =  { shape: "rectangle", length: number, width: number };

    function throwOnNever(x: {shape: string}): never {
        throw new Error(`Unexpected shape: ${x.shape}`);
    }

    function area(shape: Circle | Rectangle): number {    
        switch (shape.shape) {
            case "circle": return Math.PI * shape.radius * shape.radius;
            case "rectangle": return shape.length * shape.width;
            default: return throwOnNever(shape);
        }
    }

...