type-init-formals

Same as type_init_formals in Dart lints

Group
Style
Path
lint/style/type-init-formals
Default
On (recommended)
Origin
Dart lints
Rule
444 of 512
recommended

Flags a redundant type annotation on an initializing formal or super parameter (type-init-formals, adopted from package:lints).

In C(int this.x) or C(int super.x) the annotation restates a type the field (or super-parameter) already fixes, so it adds nothing and risks drifting out of sync with that declaration. It is redundant only when it names the same type: annotating a narrower one — num x; C(int this.x); — is legal Dart that meaningfully restricts the constructor's parameter, and upstream (nodeType.type == field.type) does not report it.

Falcon limitation: this rule compares written types after whitespace normalization, not semantic type equality. Target types come from explicitly declared file-local fields and non-primary superclass constructors, including forwarded super parameters. Primary-constructor fields and extension-type representation fields are not visited. Missing or untyped targets are skipped. Superclass lookup uses only the final name segment, so a prefixed superclass can be confused with a local declaration. Likewise, identically spelled type parameters from different scopes can compare equal without representing the same type. A reported annotation is therefore not always safe to remove.

Invalid

example.dartdart
// Type annotations on initializing formals and super parameters.
class A {
  int x;
  double y;
  A(int this.x, double this.y);
}

class Base {
  final int a;
  Base(this.a);
}

class Derived extends Base {
  Derived(int super.a);
}

class C {
  String name;
  num size;
  C(String this.name);
  C.sized(num this.size);
}

class D {
  bool flag;
  D(bool this.flag);
}

// Named super parameter whose super constructor states the type outright.
class NamedBase {
  final String label;
  NamedBase({required this.label});
}

class NamedDerived extends NamedBase {
  NamedDerived({required String super.label});
}
Don't type annotate initializing formals.
4 double y;
5 A(int this.x, double this.y);
Don't type annotate initializing formals.
4 double y;
5 A(int this.x, double this.y);
Don't type annotate initializing formals.
13class Derived extends Base {
14 Derived(int super.a);
Don't type annotate initializing formals.
19 num size;
20 C(String this.name);
Don't type annotate initializing formals.
20 C(String this.name);
21 C.sized(num this.size);
Don't type annotate initializing formals.
25 bool flag;
26 D(bool this.flag);
Don't type annotate initializing formals.
35class NamedDerived extends NamedBase {
36 NamedDerived({required String super.label});

Valid

example.dartdart
// Initializing formals and super parameters without a redundant type.
class A {
  int x;
  double y;
  A(this.x, this.y);
}

class Base {
  final int a;
  Base(this.a);
}

class Derived extends Base {
  Derived(super.a);
}

class C {
  String name;
  num size;
  C(this.name);
  C.sized(this.size);
  void use() {
    print(this.name);
    return this.size.isNaN ? null : null;
  }
}

class D {
  bool flag;
  D(this.flag);
}

// A *narrowing* type annotation on an initializing formal is not redundant: it
// restricts the constructor's parameter below the field's declared type.
class Narrowing {
  num x;
  Object label;
  Narrowing(int this.x);
  Narrowing.labelled(String this.label);
}

// The same narrowing applies to super parameters.
class WideBase {
  final num a;
  final Object b;
  WideBase(this.a, {required this.b});
}

class NarrowDerived extends WideBase {
  NarrowDerived(int super.a, {required String super.b});
}

// A pattern guard puts `this.` right after a type-like token without any
// initializing formal being involved.
class Guarded {
  bool flag;
  Guarded(this.flag);
  String describe(Object value) {
    switch (value) {
      case String s when this.flag:
        return s;
      case int i when this.flag:
        return '$i';
      default:
        return '';
    }
  }
}

Configure type-init-formals

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "type-init-formals": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/style/type-init-formals: <reason>
  • unawaited-futuresunawaited_futuresrecommended

    Future results in async bodies must be awaited or marked unawaited.

  • unintended-html-in-doc-commentunintended_html_in_doc_commentrecommended

    Flags angle-bracket text in doc comments that Markdown would render as an HTML tag.

  • unnecessary-await-in-returnunnecessary_await_in_return

    Avoid await on a returned Future the function's own Future already covers.

  • unnecessary-brace-in-string-interpsunnecessary_brace_in_string_interpsrecommended

    Flags ${x} string interpolations whose braces can be dropped.

  • unnecessary-breaksunnecessary_breaksrecommended

    Flags a trailing break in a switch case that already ends implicitly.

  • unnecessary-constructor-nameunnecessary_constructor_namerecommended

    Flags a redundant .new on constructor declarations and invocations.

  • unnecessary-finalunnecessary_final

    Don't use final for local variables and parameters.

  • unnecessary-lateunnecessary_laterecommended

    Flags a redundant late modifier on an initialized static or top-level variable.