Index signature is missing in type fires when you try to use a type that has specific, named properties as if it supported arbitrary string-keyed access — TypeScript's structural typing is strict about this distinction: a type with known properties isn't automatically compatible with a type expecting dynamic key access, even if every actual property would technically satisfy it.
This error means you're assigning or comparing a value against a type expecting an index signature ({ [key: string]: T }) using a type that only declares specific named properties without that signature — commonly hit when passing a typed object into a function expecting a generic Record-like parameter, or accessing an object's properties with a dynamic string key.
Why This Error Happens
TypeScript's structural typing generally allows a more specific type to be used where a less specific one is expected, but index signatures are an exception to this in one specific direction — a type without an index signature isn't automatically assignable to a type requiring one, since TypeScript can't guarantee the specific type won't gain additional properties later that would violate the index signature's value type constraint, or that dynamic access with an arbitrary key would actually be safe.
Reproducing the Error
Passing a specifically-typed object where a generic Record is expected:
interface UserPreferences {
theme: string;
fontSize: number;
}
function serializeSettings(settings: Record<string, unknown>) {
return JSON.stringify(settings);
}
const prefs: UserPreferences = { theme: "dark", fontSize: 14 };
serializeSettings(prefs);
// Error: Argument of type 'UserPreferences' is not assignable to parameter
// of type 'Record<string, unknown>'. Index signature is missing in type 'UserPreferences'.
Dynamic key access on a specifically-typed object:
function getPref(prefs: UserPreferences, key: string) {
return prefs[key];
// Error: Element implicitly has an 'any' type because expression of type
// 'string' can't be used to index type 'UserPreferences'.
// Index signature is missing in type 'UserPreferences'.
}
Core Concepts Behind This Error
This restriction exists specifically to prevent a real category of bug — if UserPreferences were freely assignable to Record<string, unknown>, code receiving it as a Record could add arbitrary keys to it, potentially violating invariants the original UserPreferences interface was meant to guarantee; TypeScript's refusal here is protecting against genuinely unsafe operations, not being needlessly strict.
Adding an explicit index signature to your own interface is one valid fix, but it changes the type's meaning meaningfully — it now permits arbitrary additional string-keyed properties of the specified value type, which may or may not be what you actually want for that specific type.
Using keyof to constrain dynamic access to only the type's actual known keys is usually the better fix for dynamic property access, since it preserves the type's specific shape while still allowing safe, type-checked dynamic-style access limited to keys that genuinely exist.
A type assertion or Record<string, unknown> cast is the least safe option, appropriate only when you have specific external knowledge that the operation is safe and the type system's structural distinction genuinely doesn't apply to your actual use case (e.g., you're deliberately serializing and don't care about the type's specific shape).
Fixing "Index Signature Is Missing in Type"
Fix 1: For generic serialization-style functions, use keyof T generics to remain type-safe without requiring an index signature:
function serializeSettings<T extends object>(settings: T) {
return JSON.stringify(settings); // no index signature required for this operation
}
Fix 2: For dynamic property access, constrain the key parameter to keyof T:
function getPref<K extends keyof UserPreferences>(prefs: UserPreferences, key: K) {
return prefs[key]; // fully type-safe, no index signature needed
}
getPref(prefs, "theme"); // works, autocompletes, type-checked
getPref(prefs, "invalidKey"); // Error: caught at compile time, correctly
Fix 3: If you genuinely need the type to support arbitrary additional keys, add an explicit index signature, understanding this changes the type's actual contract:
interface UserPreferences {
theme: string;
fontSize: number;
[key: string]: unknown; // now genuinely permits arbitrary additional keys
}
Should You Add an Index Signature or Use keyof Generics Instead?
Use keyof T generics in the large majority of cases — it preserves your type's specific, meaningful shape while still enabling safe dynamic-style access, and it catches typos in key names at compile time that an index signature wouldn't. Add an actual index signature only when the type genuinely needs to support arbitrary, unknown-in-advance keys as part of its real semantics (a generic configuration bag, dynamic form data), since it permanently loosens what the type guarantees about its shape.
Preventing This Error in Production
Prefer keyof T-constrained generics for functions needing dynamic-style property access on specifically-typed objects, keeping the safety of named properties while still supporting flexible access patterns. Reserve actual index signatures for types that are genuinely meant to represent open-ended, dynamic key-value structures, rather than adding one reflexively just to make a type error disappear.
If you hit this error, reach for a keyof T generic constraint first — it resolves the large majority of cases without weakening your type's actual shape, and it's usually a better fix than loosening the type with an index signature.