prefer-iterable-where-type
Same as prefer_iterable_whereType in Dart lints
- Group
- Style
- Path
lint/style/prefer-iterable-where-type- Default
- On (recommended)
- Origin
- Dart lints
- Rule
- 382 of 512
Flags .where((e) => e is T), which .whereType<T>() expresses directly.
Filtering an iterable with an is test is exactly what Iterable.whereType
does, but the method also narrows the element type, yielding an
Iterable<T> instead of leaving the original element type in place. Using
whereType<T>() is shorter, avoids the throwaway closure, and removes the
casts or checks that a bare where filter would still require downstream.
The rule matches a .where call carrying exactly one positional argument and
no named arguments, where that argument is a one-parameter arrow closure of
the form param is T — the test must be non-negated and applied to the
closure's own parameter.
Semantic analysis requires declaration identities. Once available, an
unknown receiver still triggers the lint. A TypeIndex can suppress it only
when the receiver is proven not to be an Iterable and to have no
whereType member; source-resolved members and subtypes take precedence.
A user type carrying its own whereType keeps firing. Without a type index,
negative proofs are unavailable, but source-derived types are still inferred.
Invalid
void bad() {
var a = items.where((e) => e is String);
var b = list.where((x) => x is int);
var c = things.where((t) => t is Widget);
var d = values.where((v) => v is double).toList();
var e = data.where((item) => item is Map);
}
// A `List` receiver IS an Iterable (`is_subtype(List, Iterable)` is `Yes`, not
// `ProvenNo`), so `whereType<T>()` applies and the diagnostic keeps firing even
// with type knowledge attached.
void iterableReceiver(List<int> xs) {
xs.where((e) => e is int);
}
// `Custom` is not an Iterable, but it carries its own `whereType` — so
// `member_lookup` is `Found`, never `ProvenAbsent`, and the rewrite is valid.
// The diagnostic keeps firing (type knowledge suppresses only on positive proof
// that `whereType` is absent).
class Custom {
Custom where(bool Function(dynamic) test) => this;
Iterable<T> whereType<T>() => throw '';
void run() {
this.where((e) => e is String);
}
}void bad() { var a = items.where((e) => e is String); var a = items.where((e) => e is String); var b = list.where((x) => x is int); var b = list.where((x) => x is int); var c = things.where((t) => t is Widget); var c = things.where((t) => t is Widget); var d = values.where((v) => v is double).toList(); var d = values.where((v) => v is double).toList(); var e = data.where((item) => item is Map);void iterableReceiver(List<int> xs) { xs.where((e) => e is int); void run() { this.where((e) => e is String);Valid
void good() {
var a = items.whereType<String>();
var b = list.where((e) => e.isValid);
var c = things.where((e) => e is! String);
var d = values.where((e) => e is int && e > 0);
var e = data.where((a, b) => a is int);
var f = items.map((e) => e is String);
}
// `Query` is not an Iterable and has no `whereType` member, so `.whereType<T>()`
// does not exist on it: `.where((e) => e is T)` here is SUPPRESSED because the
// receiver type is positively proven. This holds for a typed parameter, for
// `this`, and for a constructor-call receiver.
// (Requires the corpus harness to attach a TypeIndex for this rule; without one
// the receiver is Unknown and these lines would fire.)
class Query {
Query where(bool Function(dynamic) test) => this;
void run(Query q) {
q.where((e) => e is String);
this.where((e) => e is int);
Query().where((e) => e is num);
}
}Configure prefer-iterable-where-type
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"prefer-iterable-where-type": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/prefer-iterable-where-type: <reason>More style rules
- prefer-last
prefer-lastFlags manual last-element indexing in favor of the
.lastgetter. - prefer-match-file-name
Match a file's sole class or enum name to its snake-case basename.
- prefer-mixin
prefer_mixinrecommendedFlags
withclauses that mix in a plain class instead of a mixin. - prefer-multi-bloc-providerbloc
Flatten directly nested
package:flutter_blocBlocProviderswithMultiBlocProvider. - prefer-multi-providerprovider
Prefer a flat
MultiProviderto directly nested provider widgets. - prefer-named-boolean-parameters
Flags explicit positional
boolparameters in private declarations and unconstrained closures. - prefer-named-parameters
Prefer named parameters when a declaration exceeds
max-number(default 1). - prefer-null-aware-method-calls
prefer_null_aware_method_callsrecommendedPrefers
f?.call()to calling a null-checked function after a!= nulltest.