Skip to content

prefer_void_callback

v0.4.0 Warning Fix Type Annotations

Flags void Function() written where the VoidCallback typedef from dart:ui would say the same thing. The quick fix replaces the type and adds the import.

Only the exact shape is reported: no parameters, and a void return. void Function(int) and int Function() are left alone — there is no typedef for them.

A callback field on a widget, spelled out longhand:

class DismissButton {
const DismissButton({required this.onPressed, this.onLongPress});
final void Function() onPressed;
final void Function()? onLongPress;
}

The same type in a function signature and a return type:

void onNextFrame(void Function() callback) {}
void Function() dismissAction(String routeName) => () {};

And in a collection of teardown work:

final List<void Function()> disposers = [];
import 'dart:ui';
class DismissButton {
const DismissButton({required this.onPressed, this.onLongPress});
final VoidCallback onPressed;
final VoidCallback? onLongPress;
}
void onNextFrame(VoidCallback callback) {}
VoidCallback dismissAction(String routeName) => () {};
final List<VoidCallback> disposers = [];

In a Flutter file VoidCallback usually needs no import of its own — it is re-exported by package:flutter/foundation.dart and by material.dart.

VoidCallback is exactly void Function(), so anything with a parameter or a different return type has no typedef to swap in:

// Takes an argument — that family is `ValueChanged<T>`.
void Function(int index) onSelected = (_) {};
// Returns a value.
int Function() itemCount = () => 0;
// Asynchronous — that one is `AsyncCallback`; see prefer_async_callback.
Future<void> Function() refresh = () async {};

See also: VoidCallback typedef

This rule is in the opinionated preset, so it is on with preset: opinionated, or by name:

many_lints.yaml
rules:
prefer_void_callback: true

To turn it off again:

many_lints.yaml
rules:
prefer_void_callback: false

To keep the rule on but skip certain paths, use per-rule exclude.