no-runtime-type-to-string

Same as no_runtimeType_toString in Dart lints

Group
Style
Path
lint/style/no-runtime-type-to-string
Default
Off, opt in
Origin
Dart lints
Rule
295 of 512

Avoid calling toString() on runtimeType.

runtimeType.toString() forces the runtime to keep type names around and is slow; in production builds the names may also be minified:

class Point {
  @override
  String toString() => '$runtimeType()'; // BAD
}

Reported for this.runtimeType, super.runtimeType, or an implicit-this runtimeType getter that is either interpolated or has toString() called on it. Uses inside asserts, throw expressions, catch clauses, mixins, and abstract classes are exempt. Extension-target checks are syntactic: an unqualified named target is checked only if it names a non-abstract class declared in this file, Object, or one of the extension's type parameters. Non-named targets, including dynamic, void, function and record types, are checked. Falcon limitation: other named targets are exempt, including prefixed targets, external classes and Never; this is not a semantic test of whether the target is concrete.

Invalid

example.dartdart
class Point {
  final int x;

  Point(this.x);

  @override
  String toString() => '$runtimeType($x)';

  String describe() => runtimeType.toString();

  String explicit() => this.runtimeType.toString();

  String viaSuper() => super.runtimeType.toString();

  String braced() => 'Instance of ${this.runtimeType}';

  void log() {
    final callback = () => print('$runtimeType');
    callback();
  }
}

enum Color {
  red;

  String label() => '$runtimeType.$name';
}

extension on Point {
  String tag() => runtimeType.toString();
}

class ExplicitDespiteShadow {
  String describe() => this.runtimeType.toString();

  void unrelated(String runtimeType) {}
}

class ExemptionRestoration {
  ExemptionRestoration()
      : assert(runtimeType.toString().isNotEmpty) {
    print('$runtimeType');
  }

  void inspect() {
    try {
      print('$runtimeType');
    } catch (error) {
      print('$runtimeType');
    } finally {
      print('$runtimeType');
    }
    print('$runtimeType');
  }
}

class PrimaryInitializer(int value) {
  this : assert(runtimeType.toString().isNotEmpty);
}

abstract class ExemptBeforeConcrete {
  String describe() => '$runtimeType';
}

class CheckedAfterAbstract {
  String describe() => '$runtimeType';
}
Using `toString` on a `Type` is not safe in production code.
6 @override
7 String toString() => '$runtimeType($x)';
Using `toString` on a `Type` is not safe in production code.
8
9 String describe() => runtimeType.toString();
Using `toString` on a `Type` is not safe in production code.
10
11 String explicit() => this.runtimeType.toString();
Using `toString` on a `Type` is not safe in production code.
12
13 String viaSuper() => super.runtimeType.toString();
Using `toString` on a `Type` is not safe in production code.
14
15 String braced() => 'Instance of ${this.runtimeType}';
Using `toString` on a `Type` is not safe in production code.
17 void log() {
18 final callback = () => print('$runtimeType');
Using `toString` on a `Type` is not safe in production code.
25
26 String label() => '$runtimeType.$name';
Using `toString` on a `Type` is not safe in production code.
29extension on Point {
30 String tag() => runtimeType.toString();
Using `toString` on a `Type` is not safe in production code.
33class ExplicitDespiteShadow {
34 String describe() => this.runtimeType.toString();
Using `toString` on a `Type` is not safe in production code.
41 : assert(runtimeType.toString().isNotEmpty) {
42 print('$runtimeType');
Using `toString` on a `Type` is not safe in production code.
46 try {
47 print('$runtimeType');
Using `toString` on a `Type` is not safe in production code.
50 } finally {
51 print('$runtimeType');
Using `toString` on a `Type` is not safe in production code.
52 }
53 print('$runtimeType');
Using `toString` on a `Type` is not safe in production code.
57class PrimaryInitializer(int value) {
58 this : assert(runtimeType.toString().isNotEmpty);
Using `toString` on a `Type` is not safe in production code.
65class CheckedAfterAbstract {
66 String describe() => '$runtimeType';

Valid

example.dartdart
abstract class Base {
  @override
  String toString() => '$runtimeType';
}

mixin Describe {
  String describe() => runtimeType.toString();
}

class Checked {
  void check(int value) {
    assert(value > 0, '$runtimeType: value must be positive');
    if (value > 10) {
      throw StateError('${runtimeType.toString()} overflow');
    }
    try {
      print(value);
    } catch (e) {
      print('$runtimeType failed: $e');
    }
  }

  String other(Object value) => value.runtimeType.toString();

  String plain() => toString();
}

class Shadowed {
  String describe(String runtimeType) => runtimeType.toString();
}

String topLevel(Object value) => '${value.runtimeType}';

extension on int {
  String tag() => runtimeType.toString();
}

class LaterShadow {
  String describe() => '$runtimeType';

  void unrelated() {
    final runtimeType = 'local';
    print(runtimeType);
  }
}

class InitializerExemptions {
  InitializerExemptions()
      : assert(runtimeType.toString().isNotEmpty, '$runtimeType');
}

// INVALID-CODE: annotation arguments need not be constant for this syntactic rule.
class IgnoredConstructorMetadata {
  @Tag(this.runtimeType.toString())
  IgnoredConstructorMetadata();

  factory IgnoredConstructorMetadata.redirect() =
      Target<void Function(@Tag(this.runtimeType.toString()) int value)>;
}

Configure no-runtime-type-to-string

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "no-runtime-type-to-string": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/style/no-runtime-type-to-string: <reason>
  • non-constant-identifier-namesnon_constant_identifier_namesrecommended

    Flags non-constant identifiers that are not written in lowerCamelCase.

  • omit-local-variable-typesomit_local_variable_types

    Flags local variable type annotations that repeat the initializer's type.

  • only-throw-errorsonly_throw_errorsrecommended

    Only throw instances of classes that extend Exception or Error.

  • package-namespackage_namesrecommendedcross-file

    Require package names to be valid lower_case_with_underscores identifiers.

  • parameter-assignmentsparameter_assignments

    Don't reassign parameters of functions, methods, or constructors.

  • parameters-ordering

    Requires named parameters to follow the explicitly configured alphabetical order.

  • pattern-fields-ordering

    Flags named object and record pattern fields that violate the configured order.

  • prefer-adjacent-string-concatenationprefer_adjacent_string_concatenationrecommended

    Flags two string literals joined with the + operator.