Не могли бы вы объяснить, почему защита от машинописи не работает - PullRequest
0 голосов
/ 14 ноября 2018

С Typescript 3.1 у меня есть следующий фрагмент кода

type Variable = string[] | File;

function isFile(variable: Variable): variable is File {
  return (variable as File).name !== undefined;
}

function getFileFromVariables(entity: EntityInterface) {
   return isFile(this.state.variables[entity.variable])
           ? this.state.variables[entity.variable]
           : undefined;
}

const file = getFileFromVariables(someEntity);

К сожалению, я не знаю, почему файл const file: string[] | File | undefined вместо const file: File | undefined

Может кто-тоскажите, почему это так и как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Ваш вопрос довольно расплывчатый.

Кроме этого, все проблемы, с которыми вы сталкиваетесь, происходят из нестрогого режима и некоторых других плохих практик.Я предлагаю вам следующее:

  • Добавьте "strict": true к compilerOptions из tsconfig.json (хотя бы временно, пока вы не найдете решение своей проблемы)
  • Определите явночто вы хотите получить от функции, например getFileFromVariables(...): File | undefined
  • Если возможно, не используйте классические функции для таких случаев.Вместо этого определите тип type GetFileFromVariables = (ent: EntityInterface) => File | undefined, затем const getFileFromVariables: GetFileFromVariables = () => ...

Тогда все сразу станет намного понятнее.

0 голосов
/ 14 ноября 2018

TypeScript не может связать вместе два экземпляра this.state.variables[entity.variable] - один передается в тип защиты, а другой используется впоследствии. Для него это два несвязанных запроса в массив, поскольку entity.variable может быть очень хорошо изменен каким-то скрытным процессом (или даже защитником типов, если он находится в той же области видимости), а система типов не может перехватить что.

Обходной путь - использовать временную переменную:

type Variable = string[] | File;

function isFile(variable: Variable): variable is File {
  return (variable as File).name !== undefined;
}

function getFileFromVariables(entity: EntityInterface) {
   const variable = this.state.variables[entity.variable];
   return isFile(variable) ? variable : undefined;
}

const file = getFileFromVariables(someEntity);

Примечание: попробуйте предоставить автономный пример, другими словами, MCVE . Ваш код было невозможно проверить, так как мы не знаем ни как выглядит EntityInterface интерфейс, ни как this или this.state. Мой ответ предполагает, что this.state.variables относится к типу Variable и EnintyInterface extends {variable: number}, и этого достаточно для того, чтобы код, предоставленный вами, дал вам результат, который вы запрашиваете, но, пожалуйста, не заставляйте нас делать такие предположения.

...