@typescript-eslint/dot-notation

Require `user.name` instead of `user["name"]`

user["name"] and user.name read the same property. The dot form is shorter and easier to read. Brackets are for keys that are computed or aren't valid names, such as headers["content-type"].

This is dot-notation with types, which lets it make exceptions for private members, protected members, and index signatures.

With bunfig.toml, turning this rule on runs it in TypeScript files and dot-notation in JavaScript files, so nothing is reported twice. With an ESLint config, turn the other rule off when you use this one.

--fix rewrites the brackets to a dot.

Configure#

Off by default. This rule needs types, so turning it on makes bun lint type check your code first.

bunfig.toml
[lint.rules]
"@typescript-eslint/dot-notation" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"@typescript-eslint/dot-notation" = ["error", {
  allowKeywords = true,
  allowPattern = "", # string
  allowPrivateClassPropertyAccess = false,
  allowProtectedClassPropertyAccess = false,
  allowIndexSignaturePropertyAccess = false,
}]

Examples#

Reported:

const user = { name: "Ada" };

console.log(user["name"]);

Not reported:

const user = { name: "Ada", "last-login": 0 };
const key = "name" as const;

console.log(user.name, user[key], user["last-login"]);

Options#

OptionDefaultWhat it does
allowKeywordstruefalse turns the rule around for reserved words: obj.class is reported, and obj["class"] is allowed.
allowPattern""A regular expression. Names that match it can be in brackets.
allowPrivateClassPropertyAccessfalseAllow brackets for private members.
allowProtectedClassPropertyAccessfalseAllow brackets for protected members.
allowIndexSignaturePropertyAccessfalseAllow brackets for keys that only an index signature declares.
const styles: Record<string, string> = {};

console.log(styles.class, styles["default"]);
const row = { user_id: 1 };

console.log(row["user_id"]);

TypeScript doesn't check private and protected on bracket access, and tests sometimes use that to reach into a class:

class Counter {
  private count = 0;
}

console.log(new Counter()["count"]);

With allowIndexSignaturePropertyAccess, brackets can mark the keys that may not be there. host is declared, so it's still reported:

interface Env {
  host: string;
  [name: string]: string;
}
declare const env: Env;

console.log(env["host"], env["PORT"]);

This option is always on when noPropertyAccessFromIndexSignature is set in your tsconfig.json, because TypeScript then rejects env.PORT:

declare const env: Record<string, string>;

console.log(env["PORT"]);