Takeshi Tokugawa YD
Takeshi Tokugawa YD

Reputation: 979

"Object is possibly 'null'" error message when non-null value guaranteed

In the below code, class field $LoadingMessage is nullable, however it will be initialized in the constructor.

export default class ImageFullScreenViewer {

  private static readonly LOADING_MESSAGE_CSS_SELECTOR_BY_ID: string = '#ImageFullScreenViewer-LoadingMessage';
  private $LoadingMessage: JQuery | null = null;

  constructor (thumbnailsContainerSelectors: string | Array<string>, adaptedPageLayoutManager: AdaptedPageLayoutManager) {
    this.$LoadingMessage = $(ImageFullScreenViewer.LOADING_MESSAGE_CSS_SELECTOR_BY_ID);
  }

  showLoadingMessage() {
    this.$LoadingMessage.show(); //  Object is possibly 'null'.
  }
}

In strict mode, TypeScript tells me that Object is possibly 'null' in the showLoadingMessage method. showLoadingMessage is non-static method, so it could not be called without ImageFullScreenViewer instance creation. As far as I know, jQuery function does not return null, so initialization with non-null value is guaranteed.

Is "TypeScript message Object is possibly 'null' is unreasonable in this case" conclusion right? (I want to crate an issue in GitHub, but TODO list before issue that they requires is too bothersome ...)

Upvotes: 0

Views: 471

Answers (1)

Matt McCutchen
Matt McCutchen

Reputation: 30929

The error is working as intended. As JB Nizet suggested, the error is based on the declared type of $LoadingMessage, which is JQuery | null. While the compiler has a "narrowing" feature that will try to determine a more specific type for a variable based on recent assignments, narrowing does not work across functions.

So if you want code to be able to assume that $LoadingMessage is non-null, you should declare the type as JQuery and remove the = null initializer; then the compiler will enforce that you assign a non-null value in the constructor. (Of course, there is a brief window before the assignment in the constructor during which $LoadingMessage is actually undefined, despite its type; this is one of the many scenarios in which TypeScript has traded off soundness for ease of use.)

Upvotes: 3

Related Questions