WIllJBD
WIllJBD

Reputation: 6164

Dart passing generic Function<T>(T t) seems to require cast, all other ways signatures don't match

With the below code as an example I can not figure out how to make the generic typed Function work with out casting as shown. Every other way I try I get some variation of

The argument type 'Null Function(Gift)' can't be assigned to the parameter type 'dynamic Function(T)'

var present = Present<Gift>(Gift('Fancy Gift'), <T>(Gift t) {
    print('${(t as Gift).name} was opened.');
  });

or

The getter 'name' isn't defined for the type 'Object'

var present = Present<Gift>(Gift('Fancy Gift'), <Gift>(t) {
    print('${t.name} was opened.');
  });

Here is the working example with a cast.

void main() {
   var present = Present<Gift>(Gift('Fancy Gift'), <T>(t) {
    print('${(t as Gift).name} was opened.');
  });
  present.open();
}


class Present<T> {
  final T _item;
  final Function<T>(T t) openedCallback;

  T open() {
    openedCallback.call(_item);
    return _item;
  }

  Present(this._item, this.openedCallback);
}

class Gift {
  final String name;

  Gift(this.name);
}

There should be a way to do this without a cast right?

Upvotes: 1

Views: 1200

Answers (1)

jamesdlin
jamesdlin

Reputation: 89926

Your class definition does not do what you intend:

class Present<T> {
  final T _item;
  final Function<T>(T t) openedCallback;
  ...

openedCallback is separately parameterized; its T type parameter is separate and independent from that of Present<T>. There is no need to parameterize openedCallback since you presumably want:

class Present<T> {
  final T _item;
  final Function(T t) openedCallback;
  ...

After that, you can do:

  var present = Present<Gift>(Gift('Fancy Gift'), (t) {
    print('${t.name} was opened.');
  });

Note that doing <T>(t) { ... } or <Gift>(t) { ... } is counterproductive. That declares an anonymous function that itself is generic and is has a type parameter named T or Gift respectively.

Upvotes: 3

Related Questions