TypeScript error

TS7053: Indexing an object with a string key

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

error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ tea: number; coffee: number; cocoa: number; }'. is reported for object[key] when key is any string and the object's type only has a fixed set of properties. The checker cannot tell which property you get, so the result would be any.

It is one of the most common errors in JavaScript code that turns on strict: lookup tables indexed by a parameter, for...in loops, and event.target.name used as a key all produce it.

At a glance

CodeTS7053
MessageElement implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'.
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

prices.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: prices.js(6,10): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ tea: number; coffee: number; cocoa: number; }'. No index signature with a parameter of type 'string' was found on type '{ tea: number; coffee: number; cocoa: number; }'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. prices.js(6,10): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ tea: number; coffee: number; cocoa: number; }'. No index signature with a parameter of type 'string' was found on type '{ tea: number; coffee: number; cocoa: number; }'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. prices.js(6,10): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ tea: number; coffee: number; cocoa: number; }'. No index signature with a parameter of type 'string' was found on type '{ tea: number; coffee: number; cocoa: number; }'. checked 21 October 2026
const prices = { tea: 3, coffee: 4, cocoa: 4.5 };

/** @param {string} drink */
export function priceOf(drink) {
  return prices[drink];error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ tea: number; coffee: number; cocoa: number; }'.
  No index signature with a parameter of type 'string' was found on type '{ tea: number; coffee: number; cocoa: number; }'.
}
Indexing an object with a string.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

What causes it

  • The key is typed string (a parameter, a for...in variable, a form field name) and the object is an object literal or a @typedef without an index signature.
  • noImplicitAny is on (part of strict).

How to fix it

Narrow the key's type

If only the object's own keys are valid, say so: @param {keyof typeof prices} drink. Callers passing an arbitrary string are then reported where it matters. For a string from outside (a URL, a form), check it first with a type guard such as isDrink in the example, written with Object.hasOwn.

prices.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 prices = { tea: 3, coffee: 4, cocoa: 4.5 };

/** @param {keyof typeof prices} drink */
export function priceOf(drink) {
  return prices[drink];
}

/** @type {Record<string, number | undefined>} */
const extras = { oatMilk: 0.5, syrup: 0.75 };

/** @param {string} name */
export function extraPrice(name) {
  return extras[name] ?? 0;
}

/**
 * @param {string} name
 * @returns {name is keyof typeof prices}
 */
export function isDrink(name) {
  return Object.hasOwn(prices, name);
}
Narrow the key, or give the object an index signature.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Or give the object an index signature

If the object is a dictionary that any key may be looked up in, type it as one: /** @type {Record<string, number | undefined>} */. Including undefined makes the result honest for missing keys. A Map is the other good choice for open-ended keys.

Gotchas

  • if (key in prices) does not narrow key, so prices[key] inside it is still TS7053; the type guard function is the JSDoc way to narrow it.
  • A cast on the key, /** @type {keyof typeof prices} */ (key), also silences the error, without any check at run time.

Sources

Last reviewed 20 October 2026.