'Typescript, how to pass "Object is possibly null" error?

I've got the "Object is possibly null" error many times and usually I use a safety "if statement" in case it returns null.

I've got the following function:

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

But overlayEl.current gets the error "Object is not defined". So I've tried:

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

Which didn't work. I've tried also:

overlay && overlayEl.current.focus();

Any hints would be highly appreciated! Thanks



Solution 1:[1]

const overlayEl = useRef() as MutableRefObject<HTMLDivElement>;

It will cast overlayEl to an initiated MutableRefObject that is the returning value of useRef:

function useRef<T = undefined>(): MutableRefObject<T | undefined>;

Yet in this case, the compiler will always think that overlayEl has a value.

Solution 2:[2]

Add a type to the ref as mentioned by @Shanon Jackson:

const linkRef = useRef<HTMLLinkElement>(null);

And then, make sure you check for null value before using current:

if (linkRef.current !== null) {
  linkRef.current.focus();
}

This will satisfy Typescript. Whereas either by itself wouldn't.

Using any or casting in order to "trick" the compiler defeats the purpose of using Typescript, don't do that.

Solution 3:[3]

I think this is more succinct than the other answers here:

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

You specify the type of the reference, and you state you know it's not null.

Solution 4:[4]

If you want to "pass/skip" then this will do it const overlayEl: any = useRef(null);

Solution 5:[5]

You can also use optional chaining which is introduced in ES2020 instead of "if" statement for cleaner code

const myRef = useRef<HTMLLinkElement>(null);

myRef.current?.focus();

You can check its browser support at caniuse.

Solution 6:[6]

If you really know that in executing time you dont have a error here then just put :

 (overlayEl as any).current 

If not, better use:

    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 ;)

Solution 7:[7]

Sometimes we useRef not only to hold an element but a value like data. somehow when I check if(something.current) return something.current not working even if i add && something.current!=null so i found that:

something.current! which says to typescript i know there is a value and bypass this issue.

Solution 8:[8]

if you want to give no chance to typescript use this :

const iframe = useRef<HTMLIFrameElement | null>(null);

     if (
   typeof iframe !== "undefined" &&
   typeof iframe.current !== "undefined" &&
   iframe.current !== null
 ) {
   iframe?.current?.contentWindow='';
   );
 }

Solution 9:[9]

Depends on what you prefer but a nice syntax and structure might be to create an interface:

interface divEL {
  current: HTMLDivElement | null;
}

This will keep your declaration clear and short and you can reuse the divEl interface for similar useRef hooks.

const overlayEl: divEL = useRef(null);

Then add focus() like this:

overlayEl.current!.focus();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TargetTaiga
Solution 2 thisismydesign
Solution 3 rosmcmahon
Solution 4
Solution 5 AbdulSamad
Solution 6
Solution 7 Maifee Ul Asad
Solution 8 kadiro
Solution 9