TS2531: Object possibly 'null'

Viewed 2153

I have below code snippet in my typescript file (React-TypeScript). But while running my app I'm getting error "object is possibly null" even after having null check

Error is thrown for last part of the if condition

anchorRef.current.contains(...)

  const anchorRef = React.useRef(null);
  const handleClose = (event: React.MouseEvent<Document, MouseEvent> | React.SyntheticEvent) => {
    if (anchorRef !== null && anchorRef.current !== null && anchorRef.current.contains(event.target)) {
      return;
    }

    setOpen(false);
  };

I recently learned TypeScript so if anyone can highlight the missing piece here then that would be great.

Thnx,
Sudhir

2 Answers

You set the initial value as null

const anchorRef = React.useRef(null);

The Typescript definitions for useRef hook are declared as follows

interface MutableRefObject<T> {
   current: T;
}
function useRef<T>(initialValue: T): MutableRefObject<T>;

interface RefObject<T> {
   readonly current: T | null;
}
function useRef<T>(initialValue: T|null): RefObject<T>;

I believe the Typescript compiler infers the type of anchorRef.current to be null, hence the complain.

A fix for it would be to explicitly set the type for the current field, e.g.


const anchorRef = React.useRef<SomeType>(null);
// 'any' also works
const anchorRef = React.useRef<any>(null);

Hi i tried to recreate your case and i found a solution to this problem. It seems that the debugger take the initialization of useRef as null and there is the reason why is complaining. I make use of the keyword as in typescript to make sort of casting of the value once i am sure i have checked the value i will cast is is not null.

export default function App() {
  const [open, setOpen] = useState<boolean>(false)
  
  const anchorRef = useRef<HTMLButtonElement>(null);
  const handleClose = (event: React.MouseEvent<Document, MouseEvent> | React.SyntheticEvent) => {
    /* if (anchorRef !== null && anchorRef.current !== null && anchorRef.current.contains(event.target)) {
      return;
    } */
    if(!anchorRef){
      return;
    }
    // yout other logic here....
    const coordinates = (anchorRef.current as HTMLButtonElement).getBoundingClientRect();
    console.log(coordinates)
    setOpen(false);
  }; 


  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button ref={anchorRef}>Click me</button>
      <div>
        I am some menu
      </div>
    </div>
  );
}

You can see after using as the debugger is not complaining anymore.

Here i let you 2 images with both examples. Using as and without it.

using as to cast value

possible null

Related