打字稿,如何传递“对象可能为空”错误?

Six*_*ght 9 typescript typescript-typings

我多次遇到“对象可能为空”错误,通常我使用安全的“ if语句”以防返回空。

我有以下功能:

const ModalOverlay = (props: any[]) => {
  const overlayEl = useRef(null);
    useEffect(() => {
    overlayEl.current.focus();
    });
    return <div {...props} ref={overlayEl} />;
  }
Run Code Online (Sandbox Code Playgroud)

但是overlayEl.current出现错误“对象未定义”。所以我尝试了:

if (!overlayEl) {
    return null
  } else {
    useEffect(() => {
    overlayEl.current.focus();
    });
    return <div {...props} ref={overlayEl} />;
  }
Run Code Online (Sandbox Code Playgroud)

哪个没有用。我也尝试过:

overlay && overlayEl.current.focus();
Run Code Online (Sandbox Code Playgroud)

任何提示将不胜感激!谢谢

小智 20

const overlayEl = useRef() as MutableRefObject<HTMLDivElement>;
Run Code Online (Sandbox Code Playgroud)

它将转换overlayEl为一个已启动的 MutableRefObject,它是 的返回值useRef

function useRef<T = undefined>(): MutableRefObject<T | undefined>;
Run Code Online (Sandbox Code Playgroud)

然而在这种情况下,编译器总是认为它overlayEl有一个值。

  • 谢谢。至少对我来说,这是正确的答案。请注意,如果您的元素是输入,则需要使用 `[...] = useRef() as MutableRefObject&lt;HTMLInputElement&gt;` (2认同)

Sha*_*son 17

当声明const overlayEl = useRef(null);时 使其输出的类型为null,因为这是它可以提供的大量信息的最佳推断,为打字稿提供更多信息,并且它将按预期工作。

尝试....

 const overlayEl = useRef<HTMLDivElement>(null);
Run Code Online (Sandbox Code Playgroud)

另外,如果您不关心未定义的语法,则可以使用一些语法糖来做这样的事情。

const overlayEl = useRef(document.createElement("div"))
Run Code Online (Sandbox Code Playgroud)

使用上述语法,所有常见的DOM方法仅返回默认值,例如“ 0”,即overlayEl.offsetWidth,getBoundingClientRect等。


thi*_*ign 12

如@Shanon Jackson 所述,向 ref 添加一个类型:

const linkRef = useRef<HTMLLinkElement>(null);
Run Code Online (Sandbox Code Playgroud)

然后,确保null在使用之前检查值current

if (linkRef.current !== null) {
  linkRef.current.focus();
}
Run Code Online (Sandbox Code Playgroud)

这将满足打字稿。而两者本身都不会。

使用any或强制转换以“欺骗”编译器违背了使用 Typescript 的目的,不要那样做。


小智 11

您还可以使用ES2020 中引入的可选链代替“if”语句以获得更清晰的代码

const myRef = useRef<HTMLLinkElement>(null);

myRef.current?.focus();
Run Code Online (Sandbox Code Playgroud)

您可以在caniuse检查其浏览器支持。


ros*_*hon 11

我认为这比这里的其他答案更简洁:

const ModalOverlay = (props: any[]) => {
  const overlayEl = useRef<HTMLDivElement>(null);
  useEffect(() => {
    overlayEl.current!.focus();
  });
  return <div {...props} ref={overlayEl} />;
}
Run Code Online (Sandbox Code Playgroud)

您指定引用的类型,并声明您知道它不为空。


Bar*_*rbu 9

如果你想“通过/跳过”那么这可以做到const overlayEl: any = useRef(null);


Nik*_*kic 5

如果您真的知道在执行时您没有错误,那么只需输入:

 (overlayEl as any).current 
Run Code Online (Sandbox Code Playgroud)

如果没有,最好使用:

    if (typeof overlayEl !== 'undefined' &&
      typeof overlayEl.current !== 'undefined' &&
      overlayEl.current === null) {          
      return;
    }

    // Or

    try {
      // you code here ...
      // This is fine way to check by order -> parent.parent.FinalInstance
      // Also try & catch will handle all bad situation about current error
      overlay &&  overlayEl.current && overlayEl.current.focus();

    } catch(e){
       console.log("Real null >> ", e);     
    }

  // Suggest if i am wrong in syntax somewhere ,this is fast answer ;)
Run Code Online (Sandbox Code Playgroud)