avoid-unnecessary-type-assertions
Same as avoid-unnecessary-type-assertions in Dart Code Metrics
- Group
- Complexity
- Path
lint/complexity/avoid-unnecessary-type-assertions- Default
- On (recommended)
- Origin
- Dart Code Metrics
- Rule
- 175 of 512
Flags an is check whose result is already guaranteed by the resolved static type.
Invalid
// Test cases for avoid-unnecessary-type-assertions rule
// Flags 'is T' checks where the variable is already known to be T
void testExplicitIntType() {
final int x = 5;
if (x is int) {
print("x is int");
}
}
void testExplicitStringType() {
final String name = "hello";
if (name is String) {
print("name is string");
}
}
void testExplicitListType() {
final List<String> items = [];
if (items is List) {
print("items is list");
}
}
void testMultipleUnnecessaryAssertions() {
final bool active = true;
final double value = 3.14;
if (active is bool) {
print("active is bool");
}
if (value is double) {
print("value is double");
}
}
class MyClass {
final int id = 42;
void checkId() {
if (id is int) {
print("id is int");
}
}
}
void testInlineAssertion() {
final String message = "test";
final result = message is String ? "yes" : "no";
}
// Regression: a nested block inherits the enclosing declarations, so a
// redundant assertion inside one is still recognised.
void nestedScopeRegression() {
final int known = 1;
{
final inBlock = known is int;
print(inBlock);
}
lbl: {
final inLabeled = known is int;
print(inLabeled);
}
}
// Regression: try/catch/finally bodies also inherit the enclosing
// declarations, the same way a plain nested block does.
void tryScopeRegression() {
final int known = 1;
try {
print(known is int);
} catch (e) {
print(known is int);
} finally {
print(known is int);
}
}
void typedCollectionForAssertionRegression() {
final list = [
for (int i = 0; i < 2; i++) i is int,
];
final map = {
for (int j = 0; j < 2; j++) j: j is int,
};
print([list, map]);
}
// Initializing an `int?` local with an `int` promotes it to `int`; Dart 3.13.5
// `dart analyze` reports unnecessary_type_check here.
void testCheckPromotedOnInitialization() {
int? maybeInt = 5;
if (maybeInt is int) {
print("maybeInt is int");
}
} final int x = 5; if (x is int) { final String name = "hello"; if (name is String) { final List<String> items = []; if (items is List) { if (active is bool) { if (value is double) { void checkId() { if (id is int) { final String message = "test"; final result = message is String ? "yes" : "no"; { final inBlock = known is int; lbl: { final inLabeled = known is int; try { print(known is int); } catch (e) { print(known is int); } finally { print(known is int); final list = [ for (int i = 0; i < 2; i++) i is int, final map = { for (int j = 0; j < 2; j++) j: j is int, int? maybeInt = 5; if (maybeInt is int) {Valid
// Good examples for avoid-unnecessary-type-assertions rule
// Type checks where the type is not already known
void testDynamicTypeCheck() {
dynamic value = 42;
if (value is int) {
print("value is int");
}
}
void testObjectTypeCheck() {
Object obj = "hello";
if (obj is String) {
print("obj is string");
}
}
void testParameterTypeCheck() {
void checkType(dynamic param) {
if (param is bool) {
print("param is bool");
}
}
}
void testNullableTypeCheck() {
int? maybeInt = int.tryParse('5');
if (maybeInt is int) {
print("maybeInt is int");
}
}
void testBroadTypeCheck() {
List<dynamic> items = [];
if (items is List<String>) {
print("items is List<String>");
}
}
void testInheritanceTypeCheck() {
Object shape = Circle();
if (shape is Circle) {
print("shape is Circle");
}
}
class Circle {}Configure avoid-unnecessary-type-assertions
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"complexity": {
"avoid-unnecessary-type-assertions": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/complexity/avoid-unnecessary-type-assertions: <reason>More complexity rules
- avoid-unnecessary-type-casts
avoid-unnecessary-type-castsrecommendedFlags an
ascast to the operand's resolved static type. - 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.