map_keys_ordering
Flags a map literal whose keys are not in the order you configure.
A long map literal is a lookup table, and an unordered one has to be read end to end to answer “is this key here?”. Ordering keeps a diff honest too: a new key lands in the middle where it can be seen, rather than appended at the end beside a duplicate nobody noticed.
This rule is in the pedantic preset, which sets order: alphabetical. Under any other preset it reports nothing until you set order: — many map literals are deliberately ordered by meaning, and alphabetising a theme map that runs lightest to darkest is a regression.
many_lints: rules: map_keys_ordering: order: alphabetical min_entries: 5rules: map_keys_ordering: order: alphabetical min_entries: 5With order: alphabetical:
const labels = { 'banana': 'Banana', 'apple': 'Apple', 'cherry': 'Cherry', 'date': 'Date', 'elder': 'Elderberry',};const labels = { 'apple': 'Apple', 'banana': 'Banana', 'cherry': 'Cherry', 'date': 'Date', 'elder': 'Elderberry',};Examples
Section titled “Examples”min_entries keeps short maps out of it
Section titled “min_entries keeps short maps out of it”Below the threshold a reader takes in the whole literal at once and order costs nothing. The default is 5, so a four-entry map is never reported:
rules: map_keys_ordering: order: alphabetical// Not reported — four entries, under the default min_entries: 5const shortcuts = { 'save': 'Ctrl+S', 'copy': 'Ctrl+C', 'cut': 'Ctrl+X', 'undo': 'Ctrl+Z',};Lower it if you want short maps checked too:
rules: map_keys_ordering: order: alphabetical min_entries: 3// Don't — now reported at three entriesconst shortcuts = { 'save': 'Ctrl+S', 'copy': 'Ctrl+C', 'undo': 'Ctrl+Z',};
// Doconst shortcuts = { 'copy': 'Ctrl+C', 'save': 'Ctrl+S', 'undo': 'Ctrl+Z',};Identifier and enum keys sort by their name
Section titled “Identifier and enum keys sort by their name”Keys do not have to be strings. A plain identifier, an enum constant or any dotted access sorts on the final name:
rules: map_keys_ordering: order: alphabeticalenum Status { active, archived, closed, draft, pending }
// Don't — sorted on `closed`, `active`, ... not on `Status.`const badges = { Status.closed: 'Closed', Status.active: 'Active', // LINT Status.archived: 'Archived', Status.draft: 'Draft', Status.pending: 'Pending',};
// Doconst badges = { Status.active: 'Active', Status.archived: 'Archived', Status.closed: 'Closed', Status.draft: 'Draft', Status.pending: 'Pending',};by_length
Section titled “by_length”rules: map_keys_ordering: order: by_length// Don'tconst units = { 'kilometre': 'km', 'metre': 'm', // LINT 'foot': 'ft', 'inch': 'in', 'yard': 'yd',};
// Doconst units = { 'foot': 'ft', 'inch': 'in', 'yard': 'yd', 'metre': 'm', 'kilometre': 'km',};Scope it where the order carries meaning
Section titled “Scope it where the order carries meaning”rules: map_keys_ordering: order: alphabetical exclude: ['lib/**/theme/**']// lib/design/theme/shades.dart — not reported, the order is the pointconst grey = { 'lightest': 0xFFF5F5F5, 'light': 0xFFE0E0E0, 'mid': 0xFF9E9E9E, 'dark': 0xFF616161, 'darkest': 0xFF212121,};Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
order |
string | — |
alphabetical, alphabetical_case_sensitive or by_length. Unset means the rule is silent |
min_entries |
int | 5 |
How many entries a literal needs before order is checked |
Known limitations
Section titled “Known limitations”One computed key skips the whole literal. A key that is a function call, an interpolated string or any other expression has no name to sort by. Rather than order the rest around an entry it cannot place, the rule leaves the literal alone entirely.
// Not reported — `resolveKey()` has no sortable namefinal config = { 'zebra': 1, resolveKey(): 2, 'apple': 3, 'mango': 4, 'kiwi': 5,};A spread, if or for element skips it too. The literal’s contents are not statically ordered at all, so there is nothing to check:
// Not reportedfinal merged = { 'zebra': 1, ...defaults, 'apple': 2, 'mango': 3, 'kiwi': 4,};Only the first out-of-order key is reported, so one misplaced entry does not produce a wall of diagnostics. No quick fix is offered — reordering entries is a mechanical edit, but a map literal frequently carries comments tied to particular lines, and moving keys past them silently mismatches the two.
Turning this rule off
Section titled “Turning this rule off”To disable this rule:
rules: map_keys_ordering: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”arguments_ordering— Keep named arguments in a configured order.initializers_ordering— Keep constructor initializers in field order.member_ordering— Keep class members in a configured order.parameters_ordering— Keep named parameters in a configured order.