oxc-project/oxc · warning · OxcDiagnostic
A record is preferred over an index signature.
Error message
A record is preferred over an index signature.
What it means
Warning from typescript/consistent-indexed-object-style (crates/oxc_linter/src/rules/typescript/consistent_indexed_object_style.rs:36). With the default option 'record', types keyed by strings/numbers must use Record<K, V> utility syntax; it fires on index signatures like '{ [key: string]: unknown }' and suggests a Record alternative in the help text.
Source
Thrown at crates/oxc_linter/src/rules/typescript/consistent_indexed_object_style.rs:36
rule::{DefaultRuleConfig, Rule},
};
fn consistent_indexed_object_style_diagnostic(
preferred: ConsistentIndexedObjectStyleConfig,
span: Span,
) -> OxcDiagnostic {
let (warning_message, help_message) = match preferred {
ConsistentIndexedObjectStyleConfig::Record => (
"A record is preferred over an index signature.",
"Use a record type such as `Record<string, unknown>` instead of an index signature.",
),
ConsistentIndexedObjectStyleConfig::IndexSignature => (
"An index signature is preferred over a record.",
"Use an index signature such as `{ [key: string]: unknown }` instead of a record type.",
),
};
OxcDiagnostic::warn(warning_message).with_help(help_message).with_label(span)
}
#[derive(Debug, Clone, Default, Deserialize)]
pub struct ConsistentIndexedObjectStyle(ConsistentIndexedObjectStyleConfig);
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "kebab-case")]
enum ConsistentIndexedObjectStyleConfig {
/// When set to `record`, enforces the use of a `Record` for indexed object types, e.g. `Record<string, unknown>`.
#[default]
Record,
/// When set to `index-signature`, enforces the use of indexed signature types, e.g. `{ [key: string]: unknown }`.
IndexSignature,
}
declare_oxc_lint!(
/// ### What it does
///View on GitHub (pinned to e1e7af627c)
Solutions
- Rewrite as 'Record<string, unknown>' / 'Record<number, Foo>'
- When the type also has named members, split it: keep the interface for named members and add a Record-typed intersection or an index property typed as Record
- If index signatures are the house style, set the option to 'index-signature' in .oxlintrc.json
Example fix
// before
type Dict = { [key: string]: unknown };
// after
type Dict = Record<string, unknown>; Defensive patterns
Strategy: validation
Validate before calling
const INDEX_SIG = /\[\s*(key|k)?\s*:\s*(string|number|symbol)\s*\]\s*:/;
if (INDEX_SIG.test(source)) fail('index signature found; prefer Record<K, V>'); Type guard
function isRecordOf<V>(v: unknown): v is Record<string, V> {
return typeof v === 'object' && v !== null;
} Prevention
- Default to Record<string, unknown> for dictionaries in style guides
- Remember interfaces needing named members plus indexing stay as interfaces (rule cannot always fix)
- Run the rule in CI on changed files to stop new index signatures
When it happens
Trigger: oxlint runs with the default (or explicit) 'indexedObjectStyle': 'record' and the file declares 'type Dict = { [key: string]: unknown };', a parameter typed '{ [k: number]: Foo }', or an interface with an index signature member.
Common situations: Enabling recommended presets over a codebase that predates Record; mixing styles after merging projects; interfaces that legitimately need both named members and an index signature (Record cannot express named members directly).
Related errors
- An index signature is preferred over a record.
- Type can be trivially inferred from the initializer
- Prefer using inline type specifiers instead of a top-level t
- Prefer using a top-level type-only import instead of inline
- Prefer using a top-level type-only import instead of inline
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/9bc865e36d488f28.
Report an issue: GitHub.