typescript/prefer-readonly-index-signature
Require readonly index signatures in TypeScript type declarations.
Targeted pattern scope
This rule targets writable TSIndexSignature nodes.
What this rule reports
This rule reports index signatures where the readonly modifier is missing.
Why this rule exists
Readonly index signatures communicate immutability intent and reduce accidental mutation of dictionary-like objects.
❌ Incorrect
interface UserLookup {
[id: string]: User;
}
type CountByKey = {
[key: string]: number;
};
✅ Correct
interface UserLookup {
readonly [id: string]: User;
}
type CountByKey = {
readonly [key: string]: number;
};
Behavior and migration notes
This rule is autofixable. The fixer inserts readonly before each reported
index signature.
Additional examples
type Cache = {
[name: string]: string;
};
// ❌ reported
type CacheView = {
readonly [name: string]: string;
};
// ✅ valid
ESLint flat config example
import etcMisc from "eslint-plugin-etc-misc";
export default [
{
plugins: { "etc-misc": etcMisc },
rules: {
"etc-misc/typescript/prefer-readonly-index-signature": "error",
},
},
];
When not to use it
Disable this rule if mutable index signatures are an intentional design choice.
Package documentation
Rule catalog ID: R109
Further reading
Adoption resources
- Start at warning level in CI, then move to error after cleanup.
- Use focused codemods/autofix batches per package or directory.