Skip to main content

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.