Skip to content

prefer_iterable_of

v0.3.0 Warning Fix Collection & Type

Flags List.from() and Set.from() where the source element type already fits the target. .from() takes Iterable<dynamic> and casts at runtime; .of() is statically typed, so a mismatch is a compile error instead of a crash. The quick fix rewrites it.

Copying a list to make it mutable is the everyday case, and .from() throws away the element type on the way through:

List<String> editableCopy(List<String> tags) {
return List<String>.from(tags);
}
List<String> editableCopy(List<String> tags) {
return List<String>.of(tags);
}

Same result, but the compiler now checks that tags really holds Strings. Under .from() a List<Object> slips in and fails later, at the first read.

.of() accepts a subtype source, so an upcast copy needs no runtime check either:

// Don't
final scores = <int>[90, 85];
final asNums = List<num>.from(scores);
// Do
final asNums = List<num>.of(scores);
// Don't
final unique = Set<String>.from(tags);
// Do
final unique = Set<String>.of(tags);

.from() earns its runtime cast when you are genuinely narrowing — the source holds a supertype and you are asserting the contents are narrower. That is not reported:

final mixed = <num>[1, 2, 3];
// Accepted: int is not guaranteed by the source type, so the cast is the point
final ints = List<int>.from(mixed);

Only List and Set are checked. Map.from() has no .of() counterpart with the same signature and is never reported.

A dynamic target always reports. List.from(source) with no type argument infers List<dynamic>, where .from() and .of() are equivalent — so .of() is preferred as the clearer default.

The source must have a resolvable element type. A dynamic source, or one the analyzer cannot infer, is left alone.

See also: List.of | Set.of

This rule is in the recommended preset, so it is on with preset: recommended or preset: opinionated. Add it to preset: core with prefer_iterable_of: true.

To turn it off:

many_lints.yaml
rules:
prefer_iterable_of: false

To keep the rule on but skip certain paths, use per-rule exclude.