eslint-plugin-no-indexed-access-prop
v0.1.3
Published
ESLint and Oxlint plugin that forbids TypeScript indexed access property types.
Maintainers
Readme
eslint-plugin-no-indexed-access-prop
ESLint- and Oxlint-compatible rule for forbidding TypeScript indexed access types such as User['id'] or T[K].
GPT-5.4, for reasons known only to its silicon soul, tends to get a little overexcited about indexed property access. This rule exists to curb that enthusiasm just enough to keep your types readable and your contracts honest.
The package exports one rule:
no-indexed-access-prop
What it flags
Examples reported by default:
type UserId = User['id'];
type Value<T, K extends keyof T> = T[K];
type UserValue = User['id' | 'name'];The rule can also be configured more narrowly:
- block all indexed access types
- block only literal property access such as
T['id'] - block only selected literal property names such as
['id', 'name']
Suggestions
The rule provides safe editor suggestions when the replacement can be derived from local syntax alone.
Example:
type UserId = { id: string }['id'];Suggested replacement:
type UserId = string;Suggestions are intentionally not emitted for cases that would require cross-file or type-aware resolution, such as:
type UserId = User['id'];
type Value<T, K extends keyof T> = T[K];Installation
ESLint
npm install --save-dev eslint eslint-plugin-no-indexed-access-propOxlint
npm install --save-dev oxlint eslint-plugin-no-indexed-access-propUsage
ESLint flat config
import noIndexedAccessProp from 'eslint-plugin-no-indexed-access-prop';
export default [
{
files: ['**/*.{ts,tsx}'],
plugins: {
noIndexedAccessProp,
},
rules: {
'noIndexedAccessProp/no-indexed-access-prop': 'error',
},
},
];Oxlint
Using an explicit alias keeps the rule name stable and short:
{
"jsPlugins": [
{
"name": "no-indexed-access-prop",
"specifier": "eslint-plugin-no-indexed-access-prop"
}
],
"rules": {
"no-indexed-access-prop/no-indexed-access-prop": "error"
}
}Options
The rule accepts a single options object.
mode
Controls which indexed access forms are reported.
"all"(default): report every indexed access type"literal-only": report only string-literal access such asT['id']orT['id' | 'name']"configured-only": report only configured literal property names
allowGenericIndex
Only meaningful in mode: "all".
When true, generic or non-literal indexed access such as T[K] is allowed, while literal property access is still reported.
allowUnionLiteralIndex
When true, union-literal access such as T['id' | 'name'] is allowed.
This exemption applies in every mode.
properties
Required when mode: "configured-only".
Specifies the blocked literal property names.
Configuration examples
Block everything
{
"rules": {
"no-indexed-access-prop/no-indexed-access-prop": "error"
}
}Block only literal property access
{
"rules": {
"no-indexed-access-prop/no-indexed-access-prop": [
"error",
{ "mode": "literal-only" }
]
}
}Block only selected properties
{
"rules": {
"no-indexed-access-prop/no-indexed-access-prop": [
"error",
{ "mode": "configured-only", "properties": ["id", "name"] }
]
}
}Allow T[K] but still block literal property access
{
"rules": {
"no-indexed-access-prop/no-indexed-access-prop": [
"error",
{ "mode": "all", "allowGenericIndex": true }
]
}
}Allow union-literal access
{
"rules": {
"no-indexed-access-prop/no-indexed-access-prop": [
"error",
{ "mode": "literal-only", "allowUnionLiteralIndex": true }
]
}
}Option migration
Older examples may show this shape:
{ "properties": ["id"] }That shape has been replaced. Use:
{ "mode": "configured-only", "properties": ["id"] }Development
npm install
npm testRelease automation helpers
This repository includes release scripts for bumping versions, tagging the current version, and creating a GitHub Release for the current version tag.
Version bump helpers use npm version, so they update package.json and package-lock.json, create a release commit, and create the matching git tag automatically.
npm run release:bump:patch
npm run release:bump:minor
npm run release:bump:majorNon-destructive previews are also available:
npm run release:bump:patch:dry-run
npm run release:bump:minor:dry-run
npm run release:bump:major:dry-runIf you already have the desired version committed and only need the matching tag, use:
npm run release:tag-currentThat command is idempotent: if v<current package.json version> already exists, it does nothing. It also refuses to create a new tag from a dirty working tree, so you do not accidentally tag the wrong commit.
To create a GitHub Release for the current version tag with generated notes, use:
npm run release:github-currentA dry-run preview is also available:
npm run release:github-current:dry-runThat command is also idempotent: if a GitHub Release for v<current package.json version> already exists, it does nothing. It requires the matching tag to already exist on origin.
When you're ready to publish the release commit and tags, push them explicitly, then create the GitHub Release:
git push
git push --tags
npm run release:github-current