2
void main() {
 foo(() {});
 foo((_) {});
}

void foo(Function callback) => null;

How can I limit callback to only have either VoidCallback or ValueChanged. Currently, it accepts all types of Function.

iDecode
  • 22,623
  • 19
  • 99
  • 186

2 Answers2

1

You cannot. What would you even do with such a datatype?

In other languages, you would use method overloading and have two methods, one for each type. Dart does not support that, see Why does dart not allow method overloading?

You can have two differently named methods though.

If you have some value with your callback that a ValueChanged method can make use of, then use that datatype. A consumer having only a VoidCallback will have to ignore the parameter, just as you did in your code.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • "What would you even do with such a datatype?" -- I'm not looking for a datatype, I thought I could do some kind of overloading or create such `typedef`. Thanks for your answer. – iDecode May 26 '21 at 05:47
1

You cannot limit callback to VoidCallback or to ValueChanged at compilation time. You could use runtime checks:

void foo(Function callback) {
  if (callback is! VoidCallback && callback is! ValueChanged) {
    throw ArgumentError(
        'Only VoidCallback and ValueChanged callbacks are allowed');
  }
  // ...
}

However, I don't recommend that since it makes your API harder to use. As an example, see Future.catchError which similarly tries to accept multiple callback types and checks them at runtime. Unfortunately, it:

  • Reduces self-documentability of the code, and documentation can be awkward. (For the case of Future, the error callback documentation is confusingly in Future.then.)
  • Trades static type checks for runtime checks, which makes mistakes harder to catch.

In your case, IMO it would be simpler to always take a ValueChanged callback, and callers can trivially ignore the argument if it's not needed:

void main() {
 foo((_) {});
 foo((_) => someVoidCallback());
}

void foo<T>(ValueChanged<T> callback) => null;
jamesdlin
  • 81,374
  • 13
  • 159
  • 204