TypeScript error

TS18047: A variable that may be null, used without a check

  • Error TS18047
  • Reported with strictNullChecks
  • Reported with strict
  • Tested with TypeScript 5.9

error TS18047: 'form' is possibly 'null'. is reported when code uses a variable, parameter or property whose type includes null as if it could not be null. It is the named form of TS2531: same check, with the variable's name in the message.

The usual source in JavaScript is a DOM lookup stored in a variable at the top of a file. Checking it once, right after the lookup, narrows the type for every line after it.

At a glance

CodeTS18047
Message'{0}' is possibly 'null'.
TypeScript's categoryerror
Listed underNull, undefined and unknown
Turned on by strictNullChecks, strict
In .js files Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file

The message is TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} is filled in by tsc for each error.

What it looks like

signup.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: signup.js(4,1): error TS18047: 'form' is possibly 'null'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. signup.js(4,1): error TS18047: 'form' is possibly 'null'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. signup.js(4,1): error TS18047: 'form' is possibly 'null'. checked 21 October 2026
const form = document.querySelector("form");

form.addEventListener("submit", (event) => {error TS18047: 'form' is possibly 'null'.
  event.preventDefault();
});
A variable that holds a DOM lookup.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

What causes it

  • The variable holds the result of something that can return null (querySelector, getItem, RegExp.exec, a function whose @returns includes null).
  • strictNullChecks (part of strict) is on.

How to fix it

Check it once, early

if (!form) throw new Error(...) (or return inside a function) right after the lookup narrows form to HTMLFormElement for the rest of the scope. A clear message beats Cannot read properties of null when the markup changes.

signup.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
const form = document.querySelector("form");
if (!form) throw new Error("signup.js: no <form> on this page");

form.addEventListener("submit", (event) => {
  event.preventDefault();
});

const footer = document.querySelector("footer");
footer?.classList.add("ready");
Stop early when the element is missing.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Or use ?. where missing is fine

footer?.classList.add("ready") does nothing when the element is absent. Use it where doing nothing is the right result.

Gotchas

  • For a const, the check carries into callbacks such as the submit handler; for a let, only when nothing assigns the variable after the callback is created (TypeScript 5.4 and later). A let that is reassigned later is possibly null again inside the callback, because the checker cannot know when the callback runs.
  • For undefined the message is TS18048, and for a type that includes both, TS18049.

Sources

Last reviewed 20 October 2026.