Небезопасное назначение тернарного оператора Any value

У меня есть сомнения, связанные с машинописным текстом и тем, как я могу работать с типами объединения, чтобы он работал. В настоящее время у меня есть этот код:

   const message: string | string[] = (axiosError as Error).message
    const errorState: string | string[] = Array.isArray(message)
      ? message[0]
      : message

Проблема, которую я получаю, заключается в переменной errorStat, я знаю причину, потому что я пытаюсь получить доступ к сообщению [0], и оно может быть строкового типа и не иметь данных внутри. Я знаю, что у меня всегда есть ценность внутри сообщения.

Любая помощь?

Спасибо!

Тип errorState должен быть только string.

catgirlkelly 17.05.2022 15:44

Предоставьте минимальный воспроизводимый пример, который четко демонстрирует проблему, с которой вы столкнулись. В идеале кто-то мог бы вставить код в автономную IDE, такую ​​как Площадка TypeScript (ссылка здесь!), и сразу же приступить к решению проблемы, не создавая ее заново. Ошибка, которую вы видите, должна присутствовать, и не должно быть несвязанных ошибок или необъявленных типов или значений.

jcalz 17.05.2022 15:59
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
0
2
27
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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[].
catgirlkelly 17.05.2022 15:44
Ответ принят как подходящий

Есть ряд мест, где это споткнется.

Самый большой из них заключается в том, что 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.

Наконец, это может не быть проблемой для вашего конкретного варианта использования, но у вас есть потенциальная ошибка, если поле axiosErrormessage является пустым массивом. Средство проверки типов будет утверждать, что у вас есть массив, но затем, когда вы попытаетесь получить доступ к его значению во время выполнения, оно вернется как undefined. Это может быть приемлемо в вашей ситуации, но я не знаю.

Отличное объяснение, многому научился. Спасибо moron4hire :)

FCosta 17.05.2022 18:40

Другие вопросы по теме