Rules / Suspicious / avoid-unrelated-type-assertions

avoid-unrelated-type-assertions

lint/suspicious/avoid-unrelated-type-assertions
recommended
Same as avoid-unrelated-type-assertions · Dart Code Metrics

Flags an is check that can never succeed because the operand's type is unrelated to the tested type.

A test like 'text' is int or 42 is String is always false, so the guarded branch is dead code — usually a leftover from a refactor or a paste that carried the wrong type. Detection works from literal operands and locally declared variables initialized from literals, comparing the operand's category (String, int, double, bool, List, Map, Set) against the tested type and reporting known-incompatible pairings. Correct the test to the type you actually mean, or remove the unreachable branch.

Invalid

example.dartdart
// Test cases for avoid-unrelated-type-assertions rule
// Flags 'is T' checks that are structurally impossible

void testStringIsInt() {
  if ("hello" is int) {
    print("string is int");
  }
}

void testIntIsString() {
  if (42 is String) {
    print("int is string");
  }
}

void testDoubleIsBool() {
  if (3.14 is bool) {
    print("double is bool");
  }
}

void testListIsMap() {
  if ([1, 2, 3] is Map) {
    print("list is map");
  }
}

void testMultipleImpossibleAssertions() {
  final x = "test";
  final y = 42;
  final z = true;

  if (x is int) {
    print("x is int");
  }

  if (y is String) {
    print("y is string");
  }

  if (z is List) {
    print("z is list");
  }
}

void testStringIsMapType() {
  if ("value" is Map<String, int>) {
    print("string is map");
  }
}

void testConditionalExpressionImpossible() {
  final result = "text" is int ? "yes" : "no";
}
Type assertion can never be true — types are unrelated
4void testStringIsInt() {
5 if ("hello" is int) {
Type assertion can never be true — types are unrelated
10void testIntIsString() {
11 if (42 is String) {
Type assertion can never be true — types are unrelated
16void testDoubleIsBool() {
17 if (3.14 is bool) {
Type assertion can never be true — types are unrelated
22void testListIsMap() {
23 if ([1, 2, 3] is Map) {
Type assertion can never be true — types are unrelated
32
33 if (x is int) {
Type assertion can never be true — types are unrelated
36
37 if (y is String) {
Type assertion can never be true — types are unrelated
40
41 if (z is List) {
Type assertion can never be true — types are unrelated
46void testStringIsMapType() {
47 if ("value" is Map<String, int>) {
Type assertion can never be true — types are unrelated
52void testConditionalExpressionImpossible() {
53 final result = "text" is int ? "yes" : "no";

Valid

example.dartdart
// Good examples for avoid-unrelated-type-assertions rule
// Type checks where the assertion is possible or plausible

void testDynamicTypeCheck() {
  dynamic value = "hello";
  if (value is String) {
    print("value is string");
  }
}

void testObjectTypeCheck() {
  Object obj = 42;
  if (obj is int) {
    print("obj is int");
  }
}

void testValidTypeCheckWithParameter() {
  void checkType(dynamic param) {
    if (param is String) {
      print("param is string");
    }
  }
}

void testValidListTypeCheck() {
  dynamic data = [1, 2, 3];
  if (data is List) {
    print("data is list");
  }
}

void testValidMapTypeCheck() {
  dynamic config = {"key": "value"};
  if (config is Map) {
    print("config is map");
  }
}

void testValidNullableTypeCheck() {
  Object? value = "text";
  if (value is String) {
    print("value is string");
  }
}

void testValidUnionLikeType() {
  Object data = 42;
  if (data is int || data is String) {
    print("data is int or string");
  }
}

How to configure

Set the severity of avoid-unrelated-type-assertions in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "suspicious": {
        "avoid-unrelated-type-assertions": "error"
      }
    }
  }
}