Freezed class with generic callback

979

It looks like a flaw in Dart type system. I've encouraged something like that either. I don't know a clean workaround. You can specify not a direct function but a function wrapped into a class with a "strong" method signature. Something like that should work:

@freezed
abstract class Foo<T> with _$Foo {
  factory Foo({
    Func<T> callBackTwo,
  }) = _Foo;
}

class Func<T> {
  final String Function(T) _apply;

  Func(this._apply) : assert(_apply != null);

  String call(T value) {
    return _apply(value);
  }
}

class MyHomePage extends StatelessWidget {    
  final fooTwo = Foo<int>(Func<int>((value) => 'Result: ${value * 3}'));

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text(fooTwo.callBackTwo(14)),
      ),
    );
  }
}

It's not so good, because you are to type more. But we can minimize typing a bit:

@freezed
abstract class Foo<T> with _$Foo {
  factory Foo({
    Func<T> callBackTwo,
  }) = _Foo;

  factory Foo.from(String Function(T) arg) {
    return Foo<T>(callBackTwo: Func<T>(arg));
  }
}

class MyHomePage extends StatelessWidget {    
  final fooTwo = Foo<int>.from((value) => 'Result: ${value * 3}');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text(fooTwo.callBackTwo(14)),
      ),
    );
  }
}
Share:
979
Thierry
Author by

Thierry

I graduated in Computer Science and Engineering at UCLouvain. I worked as a software engineer and product manager for the worldwide Digital Security Company, GEMALTO (now part of THALES Group) for almost a decade before becoming an entrepreneur in China, where QR Codes are mainstream business and personal tools. Now back in Belgium, I use my experience as an entrepreneur and focus on the marketing success of companies based on information technology.

Updated on December 01, 2022

Comments

  • Thierry
    Thierry over 1 year

    I would like to define a freezed class [https://pub.dev/packages/freezed] with a generic callback.

    Freezed class:

    import 'package:freezed_annotation/freezed_annotation.dart';
    
    part 'foo.freezed.dart';
    
    @freezed
    abstract class Foo<T> with _$Foo {
      factory Foo({
        // String Function() callBackOne,
        String Function(T) callBackTwo,
      }) = _Foo;
    }
    

    Widget using the Freezed class:

    class MyHomePage extends StatelessWidget {
      // final fooOne = Foo<int>(callBackOne: () => 'Result: 42');
      final fooTwo = Foo<int>(callBackTwo: (value) => 'Result: ${value * 3}');
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text(fooTwo.callBackTwo(14)),
          ),
        );
      }
    }
    

    Error:

    lib/foo.freezed.dart:128:26: Error: The return type of the method '_Foo.callBackTwo' is 'String Function(T)', which does not match the return type, 'String Function(dynamic)', of the overridden method, '_$Foo.callBackTwo'.
    Change to a subtype of 'String Function(dynamic)'.
      String Function(T) get callBackTwo;
                             ^
    lib/foo.freezed.dart:31:26: Context: This is the overridden method ('callBackTwo').
      String Function(T) get callBackTwo;
    
                             ^
    

    Do you know what is wrong with my code? Is it a limitation of Freezed? Do you know a workaround?

    Thank you!!!