'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 |
