你能解释一下为什么打字稿防护不起作用

时间:2018-11-14 07:56:02

标签: javascript typescript typescript-typings

有了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 :(得分:0)

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界面是什么样,也不知道thisthis.state是什么。我的回答是假设this.state.variables的类型为VariableEnintyInterface extends {variable: number},并且所提供的代码足以满足您的要求,但是请不要强迫我们这样做这个假设。

答案 1 :(得分:0)

您的问题非常模糊。

除此之外,您遇到的所有问题均来自非严格模式和其他一些不良做法。我建议您执行以下操作:

  • "strict": true添加到compilerOptions的{​​{1}}中(至少暂时添加,直到找到解决问题的方法为止)
  • 明确定义要从函数中获取的内容,例如tsconfig.json
  • 在可能的情况下,请勿使用经典功能。而是先定义类型getFileFromVariables(...): File | undefined,然后再定义type GetFileFromVariables = (ent: EntityInterface) => File | undefined

然后,一切立即变得清晰起来。