[英]Could you explain why typescript guard doesn't work
With Typescript 3.1 I have got a following piece of code 使用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);
Unfortunately, I don't know why the file is const file: string[] | File | undefined
不幸的是,我不知道为什么文件是
const file: string[] | File | undefined
const file: string[] | File | undefined
const file: string[] | File | undefined
instead of const file: File | undefined
const file: string[] | File | undefined
而不是const file: File | undefined
const file: File | undefined
Could someone tell me why it's like this and how may I fix it? 有人可以告诉我为什么会这样,我该如何解决?
TypeScript isn't able to link together two instances of this.state.variables[entity.variable]
- one that is passed into type guard and another used afterwards. TypeScript无法将
this.state.variables[entity.variable]
两个实例链接在一起-一个实例传递给类型保护,另一个实例随后使用。 For it, this is two unrelated queries into array, since entity.variable
could be very well changed by some undercover process (or even by the type guard, if it is in the same scope), and type system isn't able to catch that. 为此,这是两个与数组无关的查询,因为
entity.variable
可能会被某些秘密程序(甚至在相同作用域内,甚至可以通过类型保护器)很好地更改,并且类型系统无法捕获那。
A common workaround is to use the temporary 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);
Side note: try to provide a self-contained example, in other words, an MCVE . 旁注:尝试提供一个独立的示例,即MCVE 。 Your code was impossible to check, since we don't know neither what
EntityInterface
interface looks like nor what is this
or this.state
. 您的代码无法检查,因为我们既不知道
EntityInterface
接口是什么样,也不知道this
或this.state
是什么。 My answer is assuming that this.state.variables
is of type Variable
and EnintyInterface extends {variable: number}
, and it's enough for the code provided to give you the result you ask, but please, don't force us to do this assumptions. 我的回答是假设
this.state.variables
的类型为Variable
并且EnintyInterface extends {variable: number}
,并且所提供的代码足以满足您的要求,但是请不要强迫我们执行此假设。
Your question is pretty vague. 您的问题很模糊。
Other than that, all the problems you are encountering are from non-strict mode and some other poor practices. 除此之外,您遇到的所有问题都来自非严格模式和其他一些不良实践。 I suggest you the following:
我建议您以下:
"strict": true
to compilerOptions
of tsconfig.json
(at least temporarily, until you figure out the solution to your problem) "strict": true
到compilerOptions
的tsconfig.json
(至少是暂时的,直到你找出解决问题的方法) getFileFromVariables(...): File | undefined
getFileFromVariables(...): File | undefined
getFileFromVariables(...): File | undefined
type GetFileFromVariables = (ent: EntityInterface) => File | undefined
type GetFileFromVariables = (ent: EntityInterface) => File | undefined
type GetFileFromVariables = (ent: EntityInterface) => File | undefined
, then const getFileFromVariables: GetFileFromVariables = () => ...
type GetFileFromVariables = (ent: EntityInterface) => File | undefined
,然后const getFileFromVariables: GetFileFromVariables = () => ...
Then everything instantly becomes much clearer to you. 然后,一切立即变得清晰起来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.