Codectionary / Developer documentation / TypeScript

Readonly Dictionary Index Signatures

A readonly index signature allows lookup through a dictionary reference while rejecting assignment through that signature.

What it is and why to use it

A readonly index signature allows lookup through a dictionary reference while rejecting assignment through that signature. This is useful when a consumer should inspect a configuration dictionary without receiving permission to edit arbitrary keys.

Common mistakes and limitations

A string index signature does not guarantee that every key exists; noUncheckedIndexedAccess can expose that uncertainty in reads. Readonly is shallow and is not a substitute for runtime freezing or ownership discipline.

Run this example

Use TypeScript 5.8 or later with strict checking and an ES2022 target. Save each complete example independently as example.ts, compile it, then run the generated JavaScript with a compatible Node.js installation. Compiler-only options below affect checking; they do not add runtime validation.

Terminal — compile and run

npx tsc example.ts --strict --target ES2022 --module commonjs
node example.js

Syntax

interface Labels { readonly [key: string]: string }

Examples

Readonly Dictionary Index Signatures

Standalone TypeScript 5.8+ example; expected output is explained below.

interface Labels { readonly [key: string]: string }
const source: Record<string, string> = { save: "Save" };
const labels: Labels = source;
console.log(labels["save"] ?? "Missing");
source["save"] = "Store";
console.log(labels["save"] ?? "Missing");
  1. labels provides read-only indexed access to the same object as source.
  2. The mutable source reference changes the stored value.
  3. The second read sees Store. Readonly checking does not create a snapshot or freeze the underlying object.
  4. Expected output: Save Store

Best practices

  • A string index signature does not guarantee that every key exists; noUncheckedIndexedAccess can expose that uncertainty in reads. Readonly is shallow and is not a substitute for runtime freezing or ownership discipline.
  • Keep external-input validation separate from compile-time type descriptions.

Runtime & versions

Compiled to JavaScript. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

TypeScript Handbook

Specifications & further reading