jsconfig.json option

noPropertyAccessFromIndexSignature

  • Default false
  • Since TypeScript 4.2

An index signature (Record<string, string>, or [key: string]: string in a type) accepts any key. With this option, dot access is kept for properties the type actually declares, and keys that only the index signature allows must be written with brackets: settings["locale"], not settings.locale (TS4111).

The point is that a misspelled declared property looks like a mistake again: settings.theem would otherwise be accepted as just another key. The option arrived with TypeScript 4.2 and is not part of strict.

At a glance

Write Optional: turn it on if you want dot access to mean "a property the type declares"
On the command line --noPropertyAccessFromIndexSignature
Type boolean
Default in TypeScript 5.9 false
TypeScript's description Enforces using indexed accessors for keys declared using an indexed type.

The description is quoted from TypeScript's own option list (Apache-2.0); see the notices.

Examples

main.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: main.js(11,22): error TS4111: Property 'locale' comes from an index signature, so it must be accessed with ['locale']. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. main.js(11,22): error TS4111: Property 'locale' comes from an index signature, so it must be accessed with ['locale']. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. main.js(11,22): error TS4111: Property 'locale' comes from an index signature, so it must be accessed with ['locale']. checked 21 October 2026
/**
 * @typedef {object} Settings
 * @property {string} theme
 */

/** @type {Settings & Record<string, string>} */
const settings = { theme: "dark", locale: "en-US" };

console.log(settings.theme);
console.log(settings.locale);error TS4111: Property 'locale' comes from an index signature, so it must be accessed with ['locale'].
console.log(settings["locale"]);
noPropertyAccessFromIndexSignature on: dot access to an index-signature key.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": [],
    "noPropertyAccessFromIndexSignature": true
  },
  "include": [
    "*.js"
  ]
}
main.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/**
 * @typedef {object} Settings
 * @property {string} theme
 */

/** @type {Settings & Record<string, string>} */
const settings = { theme: "dark", locale: "en-US" };

console.log(settings.theme);
console.log(settings.locale);
console.log(settings["locale"]);
noPropertyAccessFromIndexSignature off: dot access works for any key.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": [
    "*.js"
  ]
}

process.env

In @types/node, process.env is an index signature, so with this option on process.env.PORT must become process.env["PORT"]. That is the most common reason teams leave it off.

Gotchas

  • Properties the type declares (settings.theme) keep dot access; only keys that come from the index signature need brackets.

Sources

Last reviewed 20 October 2026.