oxc-project/oxc · warning · OxcDiagnostic
Prefer `.at()` over ` `.
Error message
Prefer `.at()` over `{method}`. What it means
Lint diagnostic from oxlint's `unicorn/prefer-at` rule. `Array.prototype.at` / `String.prototype.at` (ES2022) accept negative indices counted from the end, so `arr[arr.length - 1]`, `arr.slice(-1)[0]`, and `str.charAt(i)` are clunkier, more error-prone ways to index. This message interpolates the discouraged technique (`{method}` is e.g. `slice`, `charAt`) and points you at `.at()`. The rule marks fixes as `dangerous_fix` because behavior differs subtly (e.g. `charAt` vs `at` on out-of-range indices, and `at` on non-array receivers).
Solutions
- Rewrite `arr[arr.length - 1]` -> `arr.at(-1)`, `str.charAt(i)` -> `str.at(i)`, `arr.slice(-1)[0]` -> `arr.at(-1)`.
- Run `oxlint --fix` then REVIEW each diff — the fix is marked dangerous; verify receivers are real arrays/strings and targets support ES2022.
- If you must support pre-ES2022 runtimes, disable the rule: `"unicorn/prefer-at": "off"`, or set `checkAllIndexAccess: false` (default) to limit hits to length-1 patterns.
- Suppress one-off with `// oxlint-disable-next-line unicorn/prefer-at` for hot paths where bracket access is measurably faster.
Example fix
// before const last = queue[queue.length - 1]; const ch = label.charAt(0); // after const last = queue.at(-1); const ch = label.at(0);
Defensive patterns
Strategy: validation
Validate before calling
// Lint only, review before fixing (dangerous_fix): // oxlint --filter unicorn/prefer-at src/ // Then manual or reviewed autofix: oxlint --fix src/ && git diff // CI gate: oxlint --deny-warnings src/
Prevention
- Confirm the runtime support matrix (Node >= 16.6, modern browsers) before adopting `.at()`.
- Review every autofix — `at()` on out-of-range indices returns undefined vs charAt's empty string, and fixes are marked dangerous.
- Leave `checkAllIndexAccess` off unless the team wants pedantic enforcement of every bracket access.
When it happens
Trigger: `const last = items[items.length - 1];`, `const first = str.charAt(0);`, `head = list.slice(-1)[0]`, and with `checkAllIndexAccess: true` any `arr[0]`-style computed access; `getLastElementFunctions` config extends it to custom helpers. Fires during oxlint runs on ComputedMemberExpression nodes.
Common situations: Adopting the unicorn category on an older codebase yields many hits in index-heavy code (parsers, buffers, pagination). Danger: the fix changes target environments — `at()` requires ES2022 runtimes (Node 16.6+, modern browsers); older Node builds or IE11 will throw `TypeError: arr.at is not a function`. Config mistakes like enabling `checkAllIndexAccess` cause a flood of pedantic hits.
Related errors
- `Array.flatMap` performs `Array.map` and `Array.flat` in…
- Passing `length` as the end argument of a `slice` call is…
- Prefer Array#flat() over legacy techniques to flatten…
- Prefer consistent types when spreading a ternary in an…
- Prefer `find` over filtering and accessing the first result.
AI-assisted analysis of oxc-project/oxc@12cb547351 (2026-08-20).
Data as JSON: /api/errors/d8de30f156fa98a4.
Report an issue: GitHub.
Appendix: source
Thrown at crates/oxc_linter/src/rules/unicorn/prefer_at.rs:28
ComputedMemberExpression, Expression, MemberExpression, StaticMemberExpression,
UnaryOperator, VariableDeclarationKind,
},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{
AstNode,
ast_util::variable_declaration_kind,
context::LintContext,
fixer::{RuleFix, RuleFixer},
rule::Rule,
utils::{get_precedence, is_same_expression},
};
fn prefer_at_diagnostic(span: Span, method: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Prefer `.at()` over `{method}`."))
.with_help("Use `.at()` for index access.")
.with_note("https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at")
.with_label(span)
}
fn prefer_at_over_substring_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(
"Prefer `String#at()` over `String#substring()` when getting one character.",
)
.with_help("Use `.at()` for index access.")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct PreferAt(Box<PreferAtConfig>);
#[derive(Debug, Default, Clone, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]View on GitHub (pinned to 12cb547351)