TypeScript error

TS7008: A class field without a type

  • Error TS7008
  • Reported with noImplicitAny
  • Reported with strict
  • Tested with TypeScript 5.9

error TS7008: Member 'items' implicitly has an 'any[]' type. is reported for a class property whose type would fall back to any (or any[]) under noImplicitAny. In a .js file the checker types a property from the values assigned to it in the class, so the error means none of those values tells it anything: the field is declared bare (items;), or set only to [], null or undefined.

A field assigned a real value in the constructor is fine without a tag: owner in the example gets string from this.owner = owner. Empty arrays are the common trap, because [] says nothing about what will go in it.

At a glance

CodeTS7008
MessageMember '{0}' implicitly has an '{1}' type.
TypeScript's categoryerror
Listed underImplicit any
Turned on by noImplicitAny, 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} and {1} are filled in by tsc for each error.

What it looks like

cart.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: cart.js(3,3): error TS7008: Member 'items' implicitly has an 'any[]' type. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. cart.js(3,3): error TS7008: Member 'items' implicitly has an 'any[]' type. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. cart.js(3,3): error TS7008: Member 'items' implicitly has an 'any[]' type. checked 21 October 2026
export class Cart {
  items;error TS7008: Member 'items' implicitly has an 'any[]' type.
  owner;

  /** @param {string} owner */
  constructor(owner) {
    this.owner = owner;
    this.items = [];
  }
}
A class field whose only value is an empty array.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

What causes it

  • A class field is declared without an initializer and nothing in the class assigns it a typed value.
  • Every assignment is [], null or undefined, which in a .js file leave the type as any or any[].
  • noImplicitAny is on (part of strict).

How to fix it

Put a @type tag on the field

/** @type {string[]} */ on the line above items = []; gives the field its type. For a property created in the constructor, put the tag above the assignment: /** @type {string[]} */ this.items = [];. A field initialized with a value the checker can read (createdAt = new Date()) needs no tag.

cart.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 Cart {
  /** @type {string[]} */
  items = [];
  /** @type {string} */
  owner;
  createdAt = new Date();

  /** @param {string} owner */
  constructor(owner) {
    this.owner = owner;
  }
}
A @type on the field, or a value it starts with.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Gotchas

  • Properties that are only assigned in a method (not the constructor or the field list) are treated as optional, so code reading them must handle undefined.
  • A @type on a field without an initializer is also checked by strictPropertyInitialization: if the constructor does not set it, that is TS2564.

Sources

Last reviewed 20 October 2026.