TypeScript error

TS2564: A typed field the constructor never sets

  • Error TS2564
  • Reported with strictPropertyInitialization
  • Reported with strict
  • Tested with TypeScript 5.9

error TS2564: Property 'userId' has no initializer and is not definitely assigned in the constructor. is reported for a class field declared with a type (here /** @type {string} */ userId;) when neither the declaration nor the constructor gives it a value. Until something does, reading it gives undefined, which the type does not allow.

The check is strictPropertyInitialization, part of strict. It applies to fields declared in the class body; a property created only by this.x = ... in the constructor is set by definition.

At a glance

CodeTS2564
MessageProperty '{0}' has no initializer and is not definitely assigned in the constructor.
TypeScript's categoryerror
Listed underClasses, JSX and unused code
Turned on by strictPropertyInitialization, 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

session.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: session.js(4,3): error TS2564: Property 'userId' has no initializer and is not definitely assigned in the constructor. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. session.js(4,3): error TS2564: Property 'userId' has no initializer and is not definitely assigned in the constructor. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. session.js(4,3): error TS2564: Property 'userId' has no initializer and is not definitely assigned in the constructor. checked 21 October 2026
export class Session {
  /** @type {string} */
  userId;error TS2564: Property 'userId' has no initializer and is not definitely assigned in the constructor.

  startedAt = new Date();
}
A typed field the constructor never sets.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

What causes it

  • A field has a @type that does not include undefined, no initializer, and no assignment in the constructor.
  • The value is set later (in an init method, after an await), which the checker cannot follow.

How to fix it

Set it in the constructor, or allow undefined in its type

Take the value as a constructor parameter and assign it there, or give the field a starting value. If it really is empty for a while, say so: /** @type {string | undefined} */ token;, and handle the empty case where it is read.

session.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
export class Session {
  /** @type {string} */
  userId;

  /** @type {string | undefined} */
  token;

  startedAt = new Date();

  /** @param {string} userId */
  constructor(userId) {
    this.userId = userId;
  }
}
Set it in the constructor, or say it may be missing.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Gotchas

  • Assignments inside methods the constructor calls (this.reset()) do not count; the checker only looks at the constructor body itself.
  • A field with no @type and no value is TS7008 instead, the implicit any error.

Sources

Last reviewed 20 October 2026.