prefer_named_parameters
This rule flags a declaration taking more than a few positional parameters.
Why use this rule
Section titled “Why use this rule”schedule(3, 4, 5) tells the reader nothing, and swapping two arguments of the same type compiles cleanly and fails at runtime. Named parameters put the meaning at the call site, where it is read.
The threshold matters more than the principle. One or two positional parameters are usually the subject of the call — substring(0, 4), Point(x, y) — and naming them is noise, so the default budget is 2.
This rule is in the pedantic preset: the budget is a house style.
See also: Effective Dart: parameters
Four ints in a row, all interchangeable to the compiler:
class Reminder { Reminder(this.hour, this.minute, this.repeatDays, this.snoozeMinutes);
final int hour; final int minute; final int repeatDays; final int snoozeMinutes;}
// Call site: Reminder(7, 30, 5, 9) — which one is which?class Reminder { Reminder({ required this.hour, required this.minute, required this.repeatDays, required this.snoozeMinutes, });
final int hour; final int minute; final int repeatDays; final int snoozeMinutes;}
// Call site: Reminder(hour: 7, minute: 30, repeatDays: 5, snoozeMinutes: 9)One or two positional parameters stay positional — they are the subject of the call:
String slice(String value, int start) => value.substring(start);Raising or lowering the budget
Section titled “Raising or lowering the budget”many_lints: rules: prefer_named_parameters: max_positional: 3rules: prefer_named_parameters: max_positional: 3Exempting a framework signature
Section titled “Exempting a framework signature”main, onRequest and middleware are exempt out of the box. Add your own framework entry points rather than turning the rule off — dart_frog passes a route’s path segments in order, so naming them is not the author’s to decide:
rules: prefer_named_parameters: additional_ignored_names: [handleRequest, buildRoute]// Not reported: `onRequest` is in the default ignore list.void onRequest(Object context, String id, String revision, String locale) {}Known limitations
Section titled “Known limitations”Only positional parameters count. Optional positionals count too, so void f(int a, [int b, int c]) is 3.
@override is skipped. The signature belongs to the supertype.
Operators and setters are skipped. Their parameters cannot be named.
A private constructor is skipped by default. It is not an API: it is reached from one place in the same library, usually a factory assembling injected dependencies. Note that this keys on the constructor’s own name — Pipeline._(a, b, c) is exempt, but the unnamed constructor of a private class _Pipeline(a, b, c) is not:
class Pipeline { // Not reported. Pipeline._(this._storage, this._adapter, this._policy);
final Object _storage; final Object _adapter; final Object _policy;}Set ignore_private_constructors: false to include them.
Private constructors and framework entry points together accounted for 22 of 28 reports on a real codebase, which is why both are exempt by default.
Options
Section titled “Options”many_lints: rules: prefer_named_parameters: max_positional: 2 additional_ignored_names: [handleRequest] ignore_private_constructors: truerules: prefer_named_parameters: max_positional: 2 additional_ignored_names: [handleRequest] ignore_private_constructors: true| Option | Type | Default | Description |
|---|---|---|---|
max_positional |
int | 2 |
Most positional parameters a declaration may take |
ignored_names |
list of strings | [main, onRequest, middleware] |
Declarations whose signature a framework dictates |
additional_ignored_names |
list of strings | [] |
Names to add to that list |
ignore_private_constructors |
bool | true |
Skip Type._(...), which is not an API |
Turning this rule off
Section titled “Turning this rule off”To disable this rule:
rules: prefer_named_parameters: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”prefer_private_named_parameters— Prefer private named parameters (Dart 3.12+) over initializer-list boilerplate.avoid_accessing_other_classes_private_members— Make the underscore mean what everyone reads it as.avoid_commented_out_code— Detect and flag commented-out code.avoid_complex_conditions— Keep boolean conditions within an operand budget.