#typescript
Вопрос:
Я пишу некоторую документацию о TypeScript и говорю о возможной полезности never
ключевого слова, одним из которых является исчерпывающая проверка, как описано здесь:
У меня есть такой код:
type PossibleStrings = 'foo' | 'bar' | 'chaz';
function fail() : never {
throw new Error("This endpoint should never be reached");
}
function usesString(value: PossibleStrings) : number {
if (value === 'foo') {
return 1
};
if (value === 'bar') {
return 2
};
return fail();
}
Теперь я ожидал бы, что это приведет к ошибке, так как вы не сможете вернуть never
тип из этой функции.
И на самом деле, если мы просто уберем это, кажется, что функция в порядке с возвращением типа никогда:
type PossibleStrings = 'foo' | 'bar' | 'chaz';
function fail() : never {
throw new Error("This endpoint should never be reached");
}
function usesString(value: PossibleStrings) : number {
return fail();
}
Кажется… сломанным. Что здесь происходит?
Изменить: Ответ указан в документации:
Тип никогда не является подтипом и может быть присвоен каждому типу; однако ни один тип не является подтипом или не может быть присвоен никогда (кроме самого никогда). Даже любой не может быть присвоен никогда.
Есть ли способ изменить это поведение или иным образом заставить этот код вести себя так, как я хочу? т. Е. Я хочу return fail()
, чтобы он был действителен только в том случае, если все остальные ветви исчерпаны.
Комментарии:
1. Я думаю, что редактирование довольно заметно меняет вопрос. Но что вы подразумеваете под «Я хочу, чтобы возврат fail() был действителен только в том случае, если все остальные ветви исчерпаны». Разве это не то, что делает код?
2. Примечание: Вы не ставите
;
после блоков, прикрепленных к структурам управления. Вы ставите их послеreturn
операторов (если только вы намеренно не полагаетесь на автоматическую вставку точки с запятой, чего, по-видимому, нет в вашем коде). Такif (value === 'foo') { return 1 };
и должно бытьif (value === 'foo') { return 1; }
.3. Похоже, что документация Басарата здесь неверна. Я создал PR для обновления.
4. @Ти Джей Краудер — А — А-только что увидел ваш комментарий. Хорошо, спасибо.
Ответ №1:
Решение состоит в том, чтобы вместо того, чтобы полагаться на тип возвращаемой функции fail, вызывающий ошибки во время компиляции, вы использовали параметры функции fail.
type PossibleStrings = 'foo' | 'bar' | 'chaz';
function fail(value: never) : never {
throw new Error("This endpoint should never be reached");
}
function usesString(value: PossibleStrings) : number {
if (value === 'foo') {
return 1
}
if (value === 'bar') {
return 2
}
return fail(value); //Argument of type 'string' is not assignable to parameter of type 'never'.(2345)
}
Когда возможные значения полностью проверены, это больше не вызывает ошибки во время компиляции.