Rules / Complexity / avoid-unnecessary-type-casts

avoid-unnecessary-type-casts

lint/complexity/avoid-unnecessary-type-casts
recommended
Same as avoid-unnecessary-type-casts · Dart Code Metrics

Flags an as cast to a type the operand already has.

Casting a variable to its own declared type does nothing at runtime and hides the fact that no conversion occurs; remove it. Lacking full type inference, the rule tracks the non-nullable declared types of local variables and class fields and reports x as T when x's declared type matches T (same name and type arguments). A nullable-declared operand is never flagged, since a cast can still strip its nullability.

Invalid

example.dartdart
// 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>;
}
Unnecessary type cast — variable is already known to be this type
5 final int x = 5;
6 final y = x as int;
Unnecessary type cast — variable is already known to be this type
10 final String name = "hello";
11 final result = name as String;
Unnecessary type cast — variable is already known to be this type
15 final List<String> items = [];
16 final casted = items as List<String>;
Unnecessary type cast — variable is already known to be this type
22
23 final a = active as bool;
Unnecessary type cast — variable is already known to be this type
23 final a = active as bool;
24 final b = value as double;
Unnecessary type cast — variable is already known to be this type
30 void castId() {
31 final casted = id as int;
Unnecessary type cast — variable is already known to be this type
37 final String message = "test";
38 final length = (message as String).length;
Unnecessary type cast — variable is already known to be this type
42 final Map<String, int> data = {};
43 final result = data as Map<String, int>;

Valid

example.dartdart
// 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 = 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 {}

How to configure

Set the severity of avoid-unnecessary-type-casts in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "complexity": {
        "avoid-unnecessary-type-casts": "error"
      }
    }
  }
}