How to Suppress "Error Ts2533: Object Is Possibly 'Null' or 'Undefined'"?

I have a type:

type tSelectProtected = {
  handleSelector?: string,
  data?: tSelectDataItem[],

  wrapperEle?: HTMLElement,
  inputEle?: HTMLElement,
  listEle?: HTMLElement,
  resultEle?: HTMLElement,

  maxVisibleListItems?: number
}

I declare a global module-wise variable:

var $protected : tSelectProtected = {};

I'm assigning proper value in function1() scope:

$protected.listEle = document.createElement('DIV');

Later in function2() scope, I'm calling:

$protected.listEle.classList.add('visible');

I'm getting TypeScript error:

error TS2533: Object is possibly 'null' or 'undefined'

I know that I can do explicit check using if ($protected.listEle) {$protected.listEle} to calm down compiler but this seems to be very unhandy for most non trivial cases.

How this situation can or should be handled without disabling TS compiler checks?

1

29 Answers

If you know from external means that an expression is not null or undefined, you can use the non-null assertion operator ! to coerce away those types:

// Error, some.expr may be null or undefined
let x = some.expr.thing;
// OK
let y = some.expr!.thing;
12

This feature is called "strict null checks", to turn it off ensure that the --strictNullChecks compiler flag is not set.

However, the existence of null has been described as The Billion Dollar Mistake, so it is exciting to see languages such as TypeScript introducing a fix. I'd strongly recommend keeping it turned on.

One way to fix this is to ensure that the values are never null or undefined, for example by initialising them up front:

interface SelectProtected {
    readonly wrapperElement: HTMLDivElement;
    readonly inputElement: HTMLInputElement;
}

const selectProtected: SelectProtected = {
    wrapperElement: document.createElement("div"),
    inputElement: document.createElement("input")
};

See Ryan Cavanaugh's answer for an alternative option, though!

7

You can suppress if needed, by adding a comment (with CAUTION below)

// @ts-ignore: Object is possibly 'null'.

Not a direct answer to the OP's question, but in my React application with Typescript - v3.6.2
tslint - v5.20.0

And using the following code

const refToElement = useRef(null);

if (refToElement && refToElement.current) {
     refToElement.current.focus(); // Object is possibly 'null' (for refToElement.current)
}

I moved on by suppressing the compiler for that line -

const refToElement = useRef(null);

if (refToElement && refToElement.current) {
     // @ts-ignore: Object is possibly 'null'.
     refToElement.current.focus(); 
}

CAUTION

Note that since it's a compiler error and not the linter error, // tslint:disable-next-line didn't work. Also, as per the documentation, this should be used rarely, only when necessary

Maya Lin-Takahashi

Maya Lin-Takahashi

Consumer Tech & Gadget Reviewer

Maya is a hardware enthusiast who tests and reviews smart home devices, smartphones, wearables, and audio gear. She focuses on practical consumer value and build quality.