TS7053: Element implicitly has an 'any' type because the index expression can't be used to index the type

Quick answer

You indexed an object with a dynamic string key but its type has no index signature, so the result would be an implicit any. If the key is one of the object's own keys, type it as keyof typeof obj. For a dictionary, use a Record / index signature (Record<string, T>) or a real Map.

The exact error string

const colors = { red: "#f00", green: "#0f0" };
const key: string = "red";
colors[key];
// error TS7053: Element implicitly has an 'any' type because expression
// of type 'string' can't be used to index type '{ red: string; green: string; }'.
//   No index signature with a parameter of type 'string' was found.

How to diagnose it

The question is whether the object has a fixed set of keys or is a dictionary — that decides the fix:

Fix 1: key is one of the object's keys → keyof typeof

const key = "red" as keyof typeof colors;   // "red" | "green"
colors[key];                                 // ✅ typed as string

function pick(k: keyof typeof colors) { return colors[k]; }

Fix 2: it's a dictionary → index signature / Record

const counts: Record<string, number> = {};
counts["apples"] = 3;            // ✅ any string key -> number

interface Counts { [key: string]: number; }   // equivalent index signature

Fix 3: Object.keys loops

Object.keys(colors).forEach((k) => {
  const key = k as keyof typeof colors;
  console.log(colors[key]);     // ✅
});

Fix 4: truly dynamic data → Map

const m = new Map<string, number>();
m.set("apples", 3);
m.get("apples");                // number | undefined

Worked example: indexing a parsed JSON dictionary

A config or i18n file is loaded as JSON and looked up by a runtime key. Untyped, the lookup is an implicit any; type it as a Record and the access is checked:

const messages = JSON.parse(text);          // any
messages[userLocale];                        // unchecked

// type it as a dictionary:
const messages2: Record<string, string> = JSON.parse(text);
const msg = messages2[userLocale] ?? messages2["en"];   // ✅ string

For a fixed-shape config object, generate an interface from a sample with JSON to TypeScript and index with keyof typeof so misspelled keys are still caught.

TS7053 in React

// 1) a theme/styles lookup by a dynamic variant
const styles = { primary: "...", danger: "..." };
function Button({ variant }: { variant: keyof typeof styles }) {
  return <button className={styles[variant]} />;   // ✅ variant is a known key
}

// 2) controlled form state keyed by the input name
const [form, setForm] = useState<Record<string, string>>({});
const onChange = (e: React.ChangeEvent<HTMLInputElement>) =>
  setForm(f => ({ ...f, [e.target.name]: e.target.value }));   // ✅ Record key

Common variants of this message

SituationCauseFix
key is a known propertystring vs fixed keysas keyof typeof obj
dictionary objectno index signatureRecord<string, T>
Object.keys(obj).forEachkeys() returns string[]cast each key
enum/number keynumeric index expressionkeyof or numeric index signature
fully dynamic key/valueruntime-built mapMap<K, V>

Debugging checklist

Frequently Asked Questions

When should I use keyof typeof versus Record?

Use keyof typeof when the key is guaranteed to be one of a fixed object's own keys — it keeps each value's specific type. Use Record<string, T> (or an index signature) when the object is a dictionary with arbitrary string keys. keyof preserves precision; Record accepts any key.

Why does Object.keys(obj).forEach trigger TS7053?

Object.keys is typed to return string[], not (keyof typeof obj)[], because an object can have extra keys at runtime. So using each string key to index the object is a dynamic access. Cast the key inside the loop: const k = key as keyof typeof obj.

Does adding an index signature weaken my types?

Somewhat: with { [k: string]: T } TypeScript will allow any string key and won't flag typos, and (with noUncheckedIndexedAccess) results become T | undefined. For a true dictionary that's correct; for a fixed-shape object, prefer keyof typeof so misspelled keys are still caught.

When is a Map better than an indexed object?

When keys are genuinely dynamic, added/removed at runtime, or not strings (numbers, objects). Map<K, V> gives get/set/has with clean typing and no index-signature workarounds, and .get() returns V | undefined so you handle misses explicitly.

Why does enabling a flag suddenly cause TS7053?

TS7053 is gated by noImplicitAny (part of strict). Turning on strict mode surfaces previously-silent implicit-any index accesses. That's the check working — add the keyof/Record typing rather than disabling noImplicitAny.

Can I index a JSON object without losing type safety?

Yes. If it's a dictionary, type the parsed value as Record<string, T>. If it has fixed keys, generate an interface from a sample and index with keyof typeof. Either way the parsed value gets a real type, so the index access is checked instead of any.

Typing a JSON object?

Generate a Record or interface from a real payload with JSON to TypeScript — nothing is uploaded to a server.

JSON to TypeScript JSON Formatter All Error References
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.