avoid-type-to-string

Same as avoid_type_to_string in Dart lints

Path
lint/correctness/avoid-type-to-string
Default
On (recommended)
Origin
Dart lints
Rule
148 of 512
recommended

Avoid Type.toString() in production code, where type names may be minified.

Web and AOT builds may minify or strip type names, so a string built from a Type can differ between debug and release:

class TypeName implements Type {}
final name = TypeName().toString(); // BAD: uses `Object.toString`
if (value is Widget) {} // GOOD: compare types, not their names

Reports calls to or tear-offs of Object.toString when the target has a non-nullable subtype of dart:core Type. The target is usually the receiver's static interface type; calls without an interface-typed receiver can be affected by the enclosing declaration. A tear-off through an identifier prefix is checked only when that prefix has an interface type. Type itself (and so every runtimeType read) is never reported, because dart:core Type redeclares toString.

Invalid

example.dartdart
void foo(String Function() f) {}

class Type2 implements Type {}

class Type3 extends Type2 {}

var direct = Type2().toString();

var inherited = Type3().toString();

class Type4 implements Type {
  late var explicitThis = this.toString();
  late var implicitThis = toString();
  late var viaSuper = super.toString();

  void tearOffs() {
    foo(this.toString);
    foo(toString);
  }
}

extension E on Type2 {
  String describe() => toString();
}
Using `toString` on a `Type` is not safe in production code.
6
7var direct = Type2().toString();
Using `toString` on a `Type` is not safe in production code.
8
9var inherited = Type3().toString();
Using `toString` on a `Type` is not safe in production code.
11class Type4 implements Type {
12 late var explicitThis = this.toString();
Using `toString` on a `Type` is not safe in production code.
12 late var explicitThis = this.toString();
13 late var implicitThis = toString();
Using `toString` on a `Type` is not safe in production code.
13 late var implicitThis = toString();
14 late var viaSuper = super.toString();
Using `toString` on a `Type` is not safe in production code.
16 void tearOffs() {
17 foo(this.toString);
Using `toString` on a `Type` is not safe in production code.
17 foo(this.toString);
18 foo(toString);
Using `toString` on a `Type` is not safe in production code.
22extension E on Type2 {
23 String describe() => toString();

Valid

example.dartdart
mixin M {
  @override
  String toString() => '';
}

class Type2 with M implements Type {
  String get x => toString();
}

class Plain {
  String describe() => toString();
}

class Named {
  @override
  String toString() => 'Named';
}

void compareTypes(Object value) {
  if (value.runtimeType == int) {
    print('int');
  }
}

void otherToString(int number, Plain plain) {
  print(number.toString());
  print(plain.toString());
  print(Named().toString());
}

void interpolation(Type type) {
  print('$type');
}

void dynamicReceiver(dynamic value) {
  print(value.toString());
}

// `dart:core` `Type` redeclares `toString`, so `Type` receivers (including
// every `runtimeType` read) never resolve to `Object.toString`.
var fromRuntimeType = 7.runtimeType.toString();

void tearOff(void Function(String Function()) foo) {
  foo(7.runtimeType.toString);
}

extension E on Type {
  String describe() => toString();
}

class Widget {
  String label() => runtimeType.toString();
}

void typeParameter(Type type) {
  print(type.toString());
}

Configure avoid-type-to-string

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "avoid-type-to-string": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/correctness/avoid-type-to-string: <reason>