Безопасность типов Typescript при типизированном переключении типов - PullRequest
1 голос
/ 16 апреля 2019

У меня есть простая функция, принимающая тип объединения и boolean в качестве параметров, и мне не удается набрать его с помощью Typescript.

У меня есть этот код ( детская площадка здесь ):

type A = 'a' | 'A';

function f(a: A, b: boolean): string {
    if (b) {
        switch (a) {
            case 'a': return '';
            case 'A': return '';
        }
    } else {
        switch (a) {
            case 'a': return '';
            case 'A': return '';
        }
    }
}

Компилятор (когда strictNullChecks включен) сообщает мне Function lacks ending return statement and return type does not include 'undefined'.

Я действительно не хочу добавлять default случаев, поскольку цель здесь состоит в том, чтобы обеспечитьчто когда я добавляю новые типы в A, я правильно обрабатываю их в f.И я не вижу, какую ветку мне не хватает.

Я мог бы исправить это, написав (см. Связанную игровую площадку):

function g(a: A): string {
    switch (a) {
        case 'a': return '';
        case 'A': return '';
    }
}

function f2(a: A, b: boolean): string {
    if (b) {
        return g(a);
    } else {
        return g(a);
    }
}

(Конечно, в реальной жизни мне нужны два разныхg функций, но для проблемы с печатанием это не важно).

Как разрешить компиляции машинописи f без введения промежуточных функций, таких как g?

1 Ответ

1 голос
/ 16 апреля 2019

Вы можете добавить чехол default, чтобы исправить это, например

function f(a: A, b: boolean): string {
    if (b) {
        switch (a) {
            case 'a': return '';
            case 'A':
            default: return '';
        }
    } else {
        switch (a) {
            case 'a': return '';
            case 'A':
            default: return '';
        }
    }
}

Вы также исправляете это, используя тип never, возвращая его, например,

function f(a: A, b: boolean): string {
    if (b) {
        switch (a) {
            case 'a': return '';
            case 'A': return '';
            default:
                const _exhaustiveCheck: never = a;
                return _exhaustiveCheck;
        }
    } else {
        switch (a) {
            case 'a': return '';
            case 'A': return '';
            default:
                const _exhaustiveCheck: never = a;
                return _exhaustiveCheck;
        }
    }
}
...