У меня есть сомнения, связанные с машинописным текстом и тем, как я могу работать с типами объединения, чтобы он работал. В настоящее время у меня есть этот код:
const message: string | string[] = (axiosError as Error).message
const errorState: string | string[] = Array.isArray(message)
? message[0]
: message
Проблема, которую я получаю, заключается в переменной errorStat, я знаю причину, потому что я пытаюсь получить доступ к сообщению [0], и оно может быть строкового типа и не иметь данных внутри. Я знаю, что у меня всегда есть ценность внутри сообщения.
Любая помощь?
Спасибо!
Предоставьте минимальный воспроизводимый пример, который четко демонстрирует проблему, с которой вы столкнулись. В идеале кто-то мог бы вставить код в автономную IDE, такую как Площадка TypeScript (ссылка здесь!), и сразу же приступить к решению проблемы, не создавая ее заново. Ошибка, которую вы видите, должна присутствовать, и не должно быть несвязанных ошибок или необъявленных типов или значений.
Array.isArray()
не является типгардом. Вы можете создать один из своих своя, используя ключевое слово is
.
Поскольку вы хотите проверить только массив, вы можете использовать это. Вот предикат типа isArray
:
let message: string | string[] = 'sdsd';
const isArray = (arg: any): arg is any[] => {
return Array.isArray(arg);
}
const errorState: string | string[] = isArray(message)
? message[0]
: message
Вот предикат isStringArray для вашего использования:
const isStringArray = (arg: any): arg is string[] => {
for(let i = 0 ; i < arg.length; i++){
if(typeof arg !== 'string')
return false;
}
return Array.isArray(arg);
}
Array.isArray
является — защита типа, и здесь он сужает тип только до string[]
.
Есть ряд мест, где это споткнется.
Самый большой из них заключается в том, что Array.isArray
и isArray
охранники типа другого отвечающего только утверждают, является ли данный тип any[]
, а не какой-то конкретный T[]
. Если защита типа дает сбой, средство проверки типов точно знает, что это тип string
. Но если он проходит, программа проверки типов знает только, что это any[]
, и не может ничего понять дальше.
Если вместо этого у вас была защита типа:
function isTypedArray<T>(val: T | T[]): val is T[] {
return isArray(val);
}
Тогда средство проверки типов сможет различать string
и string[]
.
Однако затем вы сохраняете его в переменной, которую вы явно ввели как string | string[]
, поэтому, когда вы впоследствии попытаетесь использовать errorMessage
, средство проверки типов все еще будет путаться в типе. Удалите аннотацию типа из errorMessage
или измените ее на просто string
.
Наконец, это может не быть проблемой для вашего конкретного варианта использования, но у вас есть потенциальная ошибка, если поле axiosError
message
является пустым массивом. Средство проверки типов будет утверждать, что у вас есть массив, но затем, когда вы попытаетесь получить доступ к его значению во время выполнения, оно вернется как undefined
. Это может быть приемлемо в вашей ситуации, но я не знаю.
Отличное объяснение, многому научился. Спасибо moron4hire :)
Тип
errorState
должен быть толькоstring
.