avoid_banned_types
Flags any mention of a type you ban, optionally only inside the directories you name. Useful for retiring a deprecated model, keeping a platform type out of shared code, or confining a design-system widget to the layer that owns it.
This rule reports nothing until you configure it.
Why use this rule
Section titled “Why use this rule”Deprecation annotations tell you a type is going away; they do not stop new code from reaching for it. During a migration the count of remaining usages is the thing you actually want to drive to zero, and a lint turns that into a number your CI reports instead of a grep somebody remembers to run.
The second use is layering. A design system where atoms must not depend on page-level layout has no way to express that in the type system — Scaffold is importable from anywhere. Banning it inside lib/design_system/atoms/** states the constraint where it can be checked.
See also: Effective Dart: deprecation, Atomic Design
// With an entry banning 'LegacyUser':void greet(LegacyUser user) {} // LINT: parameter typeLegacyUser find() => LegacyUser('a'); // LINT: return type, and the callList<LegacyUser> all = []; // LINT: as a type argumentvoid greet(User user) {}
User find() => const User('ada');
List<User> all = [];Turning this rule off
Section titled “Turning this rule off”This rule is in no preset, so it is off unless you enable it by name:
rules: avoid_banned_types: trueTo turn it off again:
rules: avoid_banned_types: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”many_lints: rules: avoid_banned_types: banned: - deny: ['LegacyUser'] message: 'Use User instead; LegacyUser is removed in v3.' - deny: ['Scaffold'] in: ['lib/design_system/atoms/**'] message: 'Atoms must not depend on page-level layout.'rules: avoid_banned_types: banned: - deny: ['LegacyUser'] message: 'Use User instead; LegacyUser is removed in v3.' - deny: ['Scaffold'] in: ['lib/design_system/atoms/**'] message: 'Atoms must not depend on page-level layout.'| Option | Type | Default | Description |
|---|---|---|---|
banned |
list of maps | [] |
The entries to enforce. With none, the rule reports nothing |
Each entry accepts:
| Key | Type | Required | Description |
|---|---|---|---|
deny |
string or list | one of deny / deny_pattern |
Type names banned by exact match. Accepts a bare Name or a qualified package:uri#Name |
deny_pattern |
string or list | one of deny / deny_pattern |
Regular expressions, anchored to the whole name |
in |
list of globs | no | Paths, relative to the package root, where the entry applies. Omit to apply everywhere |
message |
string | no | A project-specific explanation appended to the diagnostic |
Matching is on the type’s declared name rather than the name as written, so an import prefix cannot hide a usage — p.LegacyUser matches a LegacyUser entry.
Qualify with package:uri#Name when a bare name is ambiguous. Banning Border outright would also catch a local class of that name; package:flutter/src/painting/border.dart#Border bans only Flutter’s.
Recipe: keeping heavy FP machinery out of an fpdart codebase
Section titled “Recipe: keeping heavy FP machinery out of an fpdart codebase”A common house rule is that a project uses fpdart’s Option / Either /
TaskEither but deliberately not Reader, State or the IO* family —
dependency injection goes through the DI mechanism the app already has, and
plain sync code covers the rest. This rule enforces that without needing one of
its own:
many_lints: rules: avoid_banned_types: banned: - deny: - 'package:fpdart/src/reader.dart#Reader' - 'package:fpdart/src/state.dart#State' - 'package:fpdart/src/io_option.dart#IOOption' message: 'Use Riverpod for injection and plain Dart for sync code.'rules: avoid_banned_types: banned: - deny: - 'package:fpdart/src/reader.dart#Reader' - 'package:fpdart/src/state.dart#State' - 'package:fpdart/src/io_option.dart#IOOption' message: 'Use Riverpod for injection and plain Dart for sync code.'Qualify these with the package:uri#Name form. State in particular is a name
Flutter also uses, and a bare entry would ban every State subclass in the app.
Related rules
Section titled “Related rules”avoid_banned_annotations— Ban specific annotations, optionally scoped by directory.avoid_banned_exports— Ban re-exports of specific libraries, optionally scoped by directory.avoid_banned_imports— Ban imports of specific libraries, optionally scoped by directory.avoid_banned_names— Ban specific identifiers from being used as declaration names.