Type 'X' cannot be used as an index type.
You indexed an object with something that is not a string, number or symbol.
What it means
JavaScript object keys can only be strings or symbols (numbers are coerced to strings). So an index expression must be typed string, number, symbol, or a literal union of those. Anything else — an object, an array, undefined, a union that includes them — is rejected.
The most frequent real cause is a value that is nearly a valid key: string | undefined from an optional property or an array.find(). The fix is to narrow away the invalid half, not to cast.
Reproduce it
declare const key: { a: 1 };
declare const obj: Record<string, number>;
console.log(obj[key]);
// ~~~ Type '{ a: 1; }' cannot be used as an index type.
How to fix it
Narrow away undefined
The key comes from an optional field or a lookup that may fail — by far the most common cause.
const key = form.name; // string | undefined
const value = table[key];
const key = form.name;
const value = key ? table[key] : undefined;
Index with the right property
You passed the whole object where you meant one of its fields. The compiler is pointing at a real mistake.
console.log(scores[user]);
console.log(scores[user.id]);
Type the key as a union of allowed keys
Only certain keys are valid. keyof makes that explicit and gives you autocomplete plus a compile error on typos.
function get(o: Config, k: string) { return o[k]; }
function get<K extends keyof Config>(o: Config, k: K) { return o[k]; }
Suppressing it
Casting the key with as string compiles but can produce undefined at runtime when the value really was missing. Narrowing costs one line and removes the risk.
Related errors
Hitting this while migrating to TypeScript?
Convert JavaScript to TypeScript deterministically — imports rewritten, JSDoc promoted to real types, class fields declared. No guessed types.
Open the converter