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
/**
* @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"]);jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": [],
"noPropertyAccessFromIndexSignature": true
},
"include": [
"*.js"
]
} /**
* @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"]);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
- TSConfig Reference: noPropertyAccessFromIndexSignature · TypeScript
- TypeScript 4.2 release notes · TypeScript handbook
Last reviewed 20 October 2026.