Read-only index signature
Index signature in type '{ readonly [k: string]: number; }' only permits reading.The compiler’s own words. Not translated — this is the string you pasted into a search box.
The object accepts any string key, and every one of them is read-only. This is TS2540 applied to a whole family of keys at once.
Reproduction
declare const ro: { readonly [k: string]: number } ro.x = 1
The build asserts this emits exactly this code.
Why the compiler says this
A `readonly` index signature is how you describe a lookup table that must not be edited in place — a frozen config, a memoised map you hand out, the result of a mapping you do not want mutated. The modifier applies to keys that do not exist yet, which is the part that surprises people: there is no key you can invent that will be writable.
Fixes
- 01
declare const ro: { [k: string]: number } ro.x = 1
Drop `readonly` if the table really is meant to be edited.
- 02
declare const ro: { readonly [k: string]: number } const next: { readonly [k: string]: number } = { ...ro, x: 1 }
Or spread into a new one. The original stays valid for everyone still holding it, which is the reason it was `readonly` in the first place.
Takeaway
`readonly` on an index signature is a statement about every key, present and future. It is the strongest immutability the type system offers, and it still disappears at run time.