avoid-unnecessary-type-casts
Same as avoid-unnecessary-type-casts in Dart Code Metrics
- Group
- Complexity
- Path
lint/complexity/avoid-unnecessary-type-casts- Default
- On (recommended)
- Origin
- Dart Code Metrics
- Rule
- 176 of 512
Flags an as cast to the operand's resolved static type.
Invalid
// Test cases for avoid-unnecessary-type-casts rule
// Flags 'as T' casts where the variable is already T
void testCastExplicitIntType() {
final int x = 5;
final y = x as int;
}
void testCastExplicitStringType() {
final String name = "hello";
final result = name as String;
}
void testCastExplicitListType() {
final List<String> items = [];
final casted = items as List<String>;
}
void testMultipleUnnecessaryCasts() {
final bool active = true;
final double value = 3.14;
final a = active as bool;
final b = value as double;
}
class MyClass {
final int id = 42;
void castId() {
final casted = id as int;
print(casted);
}
}
void testInlineUnnecessaryCast() {
final String message = "test";
final length = (message as String).length;
}
void testChainedUnnecessaryCast() {
final Map<String, int> data = {};
final result = data as Map<String, int>;
}
// Regression: the cast must still be found inside Dart 3 containers.
void testCastsInContainers() {
final int n = 5;
final (a, _) = (n as int, 0);
lbl: {
final b = n as int;
print(b);
}
final c = switch (n) {
0 => n as int,
_ => 0,
};
final d = switch (n as int) {
_ => 0,
};
final e = [if (n > 0) n as int];
final f = [...[n as int]];
final g = (p: n as int, q: 0);
print([a, c, d, e, f, g]);
}
// Regression: locals declared inside a loop or a try body are tracked, so a
// redundant cast there is still reported.
void loopScopeRegression(List<int> xs) {
for (final _ in xs) {
final int inLoop = 1;
print(inLoop as int);
}
try {
final int inTry = 2;
print(inTry as int);
} catch (e) {
print(e);
}
}
void typedCollectionForCastRegression() {
final list = [
for (int i = 0; i < 2; i++) i as int,
];
final map = {
for (int j = 0; j < 2; j++) j: j as int,
};
print([list, map]);
}
// Initializing an `int?` local with an `int` promotes it to `int`; Dart 3.13.5
// `dart analyze` reports unnecessary_cast here.
void testCastPromotedOnInitialization() {
int? maybeInt = 5;
final int nonNull = maybeInt as int;
print(nonNull);
} final int x = 5; final y = x as int; final String name = "hello"; final result = name as String; final List<String> items = []; final casted = items as List<String>; final a = active as bool; final a = active as bool; final b = value as double; void castId() { final casted = id as int; final String message = "test"; final length = (message as String).length; final Map<String, int> data = {}; final result = data as Map<String, int>; final int n = 5; final (a, _) = (n as int, 0); lbl: { final b = n as int; final c = switch (n) { 0 => n as int, }; final d = switch (n as int) { }; final e = [if (n > 0) n as int]; final e = [if (n > 0) n as int]; final f = [...[n as int]]; final f = [...[n as int]]; final g = (p: n as int, q: 0); final int inLoop = 1; print(inLoop as int); final int inTry = 2; print(inTry as int); final list = [ for (int i = 0; i < 2; i++) i as int, final map = { for (int j = 0; j < 2; j++) j: j as int, int? maybeInt = 5; final int nonNull = maybeInt as int;Valid
// Good examples for avoid-unnecessary-type-casts rule
// Type casts where the variable is not already known to be T
void testCastDynamicToInt() {
dynamic value = 42;
final int x = value as int;
}
void testCastObjectToString() {
Object obj = "hello";
final String name = obj as String;
}
void testCastFromParameter() {
void process(dynamic param) {
final int x = param as int;
print(x);
}
}
void testCastNullableToNonNullable() {
int? maybeInt = int.tryParse('5');
final int nonNull = maybeInt as int;
}
void testCastBroadToNarrow() {
List<dynamic> items = [1, 2, 3];
final List<int> ints = items as List<int>;
}
void testCastBetweenUnrelatedTypes() {
Object shape = Circle();
final Circle c = shape as Circle;
}
void testCastFromJsonDecode() {
dynamic json = {"id": 42};
final Map<String, dynamic> data = json as Map<String, dynamic>;
}
class Circle {}Configure avoid-unnecessary-type-casts
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"complexity": {
"avoid-unnecessary-type-casts": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/complexity/avoid-unnecessary-type-casts: <reason>More complexity rules
- cascade-invocations
cascade_invocationsFlags consecutive statements that invoke members on the same variable.
- cognitive-complexity
Reports function bodies with excessive nesting-weighted control flow.
- cyclomatic-complexity
cyclomatic_complexityFlags a function whose cyclomatic complexity exceeds the configured threshold.
- join-return-with-assignment
join_return_with_assignmentFlags an assignment immediately followed by
returnof the same variable. - max-lines-for-file
max_lines_for_fileFlags a file longer than the configured line limit.
- max-lines-for-function
max_lines_for_functionFlags a function or method longer than the configured line limit.
- max-parameters-for-function
max_parameters_for_functionFlags callable declarations and function types with more than the configured number of parameters.
- max-statements
Reports function bodies with too many statements.