对象可能为空(ts18047),即使之前进行了明确检查。

huangapple go评论70阅读模式
英文:

object possibly null (ts18047) even after previous explicit check

问题

在上面的代码中,为什么在高亮行上出现 'event.target.files' is possibly 'null' 的警告,而在前一行已经进行了 null 检查?我知道我可以使用非空断言操作符,就像在下面的代码示例中所做的那样,但可以有人解释一下这种行为吗?

对象可能为空(ts18047),即使之前进行了明确检查。

const handleOnUpload = (event: ChangeEvent<HTMLInputElement>) => {
    if (event.target.files === null || event.target.files?.length === 0) return;
    if (allowedExtensions.some((extension) => event.target.files![0].type === extension)) {
        // ...
    }
    // ...
}

编辑:当我将访问的对象存储到单独的变量中时,它不会有任何投诉:

const handleOnUpload = (event: ChangeEvent<HTMLInputElement>) => {
    if (event.target.files === null || event.target.files?.length === 0) return;
    const uploadedImage = event.target.files[0];
    if (allowedExtensions.some((extension) => uploadedImage.type === extension)) {
        // ...
    }
    // ...
}
英文:

why am I getting &#39;event.target.files&#39; is possibly &#39;null&#39; on the highlighted line when there the null check on the previous line? i know i can use non-null assertion operator, but like i did in the end as you can see in the code example below, but can someone please explain this behavior?

对象可能为空(ts18047),即使之前进行了明确检查。

const handleOnUpload = (event: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
    if (event.target.files === null || event.target.files?.length === 0) return;
    if (allowedExtensions.some((extension) =&gt; event.target.files![0].type === extension)) {
        ...
    }
    ...
}

EDIT: when i store the accessed object to a separate variable, it does not complain one bit:

const handleOnUpload = (event: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
    if (event.target.files === null || event.target.files?.length === 0) return;
    const uploadedImage = event.target.files[0];
    if (allowedExtensions.some((extension) =&gt; uploadedFile.type === extension)) {
        ...
    }
    ...
}

答案1

得分: 2

您之所以收到此警告是因为您在 Lambda 函数中访问了 event.target.files,基本上是在某个回调中进行的。TypeScript 不知道这个回调会存在多久,但它知道它会保存包含 eventevent.target.files 的闭包,而 event.target.files 可能为 null

以下是一个合成示例,说明类似的代码如何导致错误:

class CallbackHandler {
  private callback: (() => boolean) | null = null;

  setupCallback(cb: () => boolean) {
    this.callback = cb;
  }

  invoke() {
    this.callback?.();
  }
}

const event: React.ChangeEvent<HTMLInputElement> = { target: { files: [{}] } };
const callbackHandler = new CallbackHandler()
const handleOnUpload = (event: ChangeEvent<HTMLInputElement>) => {
  if (event.target.files === null || event.target.files?.length === 0) return;
  callbackHandler.setupCallback((extension) => event.target.files[0].type === extension);
}

// 设置回调函数
handleOnUpload(event);
// 现在更改事件
event.target.files = null;
// 现在调用回调函数,会出现错误
callbackHandler.invoke();
英文:

You have this warning, because you are accessing event.target.files in lambda function, basically in some callback. Typescript doesn't know how long this callback will be alive. But it knows that it stores closure with event and event.target.files is possibly null.

Here is synthetic example how similar code can lead to error:

class CallbackHandler { 
  private callback: (() =&gt; boolean) | null = null; 
  
  setupCallback(cb: () =&gt; boolean) { 
    this.callback = cb; 
  } 
  
  invoke() {
    this.callback?.();
  }
}


const event: React.ChangeEvent&lt;HTMLInputElement&gt; = { target: { files: [{}] } };
const callbackHandler = new CallbackHandler()
const handleOnUpload = (event: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
  if (event.target.files === null || event.target.files?.length === 0) return;
  callbackHandler.setupCallback((extension) =&gt; event.target.files[0].type === extension));
}

// we setup our callback 
handleOnUpload(event);
// now change event
event.target.files = null;
// now invoke callback and we get error
callbackHandler.invoke();

huangapple
  • 本文由 发表于 2023年2月24日 03:47:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75549653.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定