Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'X' shows up specifically when you access an object's property using a dynamic string key rather than a known property name — a case TypeScript's noImplicitAny setting flags because it can't verify the access is safe at compile time.
This error means you're indexing into an object with a value TypeScript can't statically prove is a valid key of that object's type — most commonly a string variable used as a bracket-notation property accessor, where TypeScript has no way to confirm at compile time that the string will actually be one of the object's real property names.
Why This Error Happens
TypeScript needs to verify every property access is type-safe. When you write obj[someKey] and someKey is typed broadly as string (rather than a specific known literal), TypeScript can't check whether someKey will actually match one of obj's declared properties — since it can't verify it, and noImplicitAny forbids falling back to any silently, it raises this error instead.
Reproducing the Error
A common version, iterating with a dynamic key:
const statusLabels = {
active: "Active",
paused: "Paused",
archived: "Archived",
};
function getLabel(status: string) {
return statusLabels[status];
// Error: Element implicitly has an 'any' type because expression of type
// 'string' can't be used to index type '{ active: string; paused: string; archived: string; }'.
}
status is a general string, but statusLabels only has three specific keys — TypeScript can't guarantee status will be one of them.
Core Concepts Behind This Error
Index signatures explicitly declare that a type can be indexed by arbitrary keys of a given type, telling TypeScript "any string key is valid here, and the value will be of this type" — adding one is the direct way to permit dynamic string indexing when that's genuinely the intended behavior.
Narrowing the key's type to a specific literal union is often the more correct fix than adding an index signature, since it preserves the guarantee that only valid keys are ever used — an index signature technically allows any string, including ones that don't actually exist as properties, silently returning undefined at runtime despite the type saying otherwise.
keyof typeof derives a literal union of an object's actual keys, which is the standard pattern for typing a parameter that should only ever be one of a specific object's known property names, keeping the type and the object in sync automatically as the object changes.
This error only appears under noImplicitAny (on by default in strict mode) — without it, TypeScript would silently infer any for the indexed access, which defeats type safety without any warning; the stricter behavior is a genuine feature, not just friction to work around.
Fixing "Element Implicitly Has an 'any' Type"
Fix 1 (preferred): Narrow the key parameter's type using keyof typeof, so only valid keys are accepted and the return type is properly inferred:
function getLabel(status: keyof typeof statusLabels) {
return statusLabels[status]; // fully type-safe, correctly inferred as string
}
getLabel("active"); // OK
getLabel("unknown"); // Error: Argument not assignable — exactly what you want
Fix 2: Add an explicit index signature when the object genuinely needs to support arbitrary string keys (a dynamic lookup table populated at runtime, for example):
const dynamicLabels: Record<string, string> = {};
dynamicLabels[someRuntimeKey] = "some value"; // OK, explicitly permitted
Fix 3: Validate the key against the object's actual keys at runtime when the key comes from genuinely external, unvalidated input (user input, an API response), rather than assuming it will always be valid:
function getLabel(status: string): string {
if (status in statusLabels) {
return statusLabels[status as keyof typeof statusLabels];
}
return "Unknown";
}
Should You Just Add an Index Signature to Make This Error Go Away?
Only when the object genuinely represents an arbitrary key-value map with no fixed set of known properties — a configuration object with dynamic runtime keys, for example. If the object has a fixed, known set of properties (as in the statusLabels example), narrowing the accessing key's type with keyof typeof is the more correct fix, since an index signature would let genuinely invalid keys pass type checking silently.
Preventing This Error in Production
Prefer keyof typeof (or an explicit literal union) over a blanket index signature whenever an object has a fixed, known set of keys, since it catches invalid key usage at compile time rather than allowing it silently. Reserve index signatures and Record<string, T> specifically for genuinely dynamic key-value structures, and validate keys from external input against the object's actual keys before indexing.
If you hit this error, resist reaching for a broad index signature as the default fix — check first whether narrowing the key's type to the object's actual known keys is the more correct, safer solution.