#typescript #typeguards
#typescript #typeguards
Вопрос:
У меня есть следующий код
const validProtocols = ["https", "http"] as const
type AllProtocols = typeof validProtocols
type Protocol = AllProtocols[number]
function isProtocol(p:unknown): p is Protocol{
return typeof p === "string" amp;amp; p in validProtocols
}
let parse = (p:string)=>{
if(isProtocol(p))
return p
else
throw `${p} is not a protocol`
}
console.log(parse("https"))
Код компилируется, но последняя строка выдает as isProtocol(p)
возвращает false . Что не так?
Код должен использоваться для проверки входных данных вне контроля компилятора, т.Е. Переменных среды.
Ответ №1:
in
Оператор проверяет, существует ли свойство для объекта. Например:
const obj = { prop: 'val' };
const arr = ['val'];
console.log('prop' in obj, 0 in arr);
Он не проверяет значения, только свойства. Чтобы проверить значения в массиве, используйте .includes
(и вам также придется обойти уродливые правила типов .includes
, которые делают подобные проверки намного более запутанными, чем можно было бы ожидать):
function isProtocol(p:unknown): p is Protocol{
return typeof p === "string" amp;amp; (validProtocols as unknown as Array<string>).includes(p)
}
Комментарии:
1. Почему приведение типов? validProtocols — это строковый массив no?
2. Он более специфичен — он напечатан как
["https", "http"]
, и, к сожалению, TypeScript не позволяет.includes
вызывать элементы, которые могут отсутствовать в массиве. Многие не согласны с дизайнерским решением, поэтому на данный момент для выполнения такой проверки вам понадобится обходной путь, такой как утверждение уродливого типа в ответе.3. Хорошо, это
as const
дополнительная информация здесь. blog.logrocket.com / … Спасибо за информацию.