rrousselGit / freezed

Code generation for immutable classes that has a simple syntax/API without compromising on the features.
https://pub.dev/packages/freezed
1.91k stars 235 forks source link

AppLocalizations as a parameter type in a typedef used as a parameter generates dynamic instead of AppLocalizations (sorry this is a weird one) #534

Open Norbert515 opened 2 years ago

Norbert515 commented 2 years ago

So when using AppLocalizations as an argument in a function typedef, and then using that typedef as a parameter of a freezed class, type information is somehow lost. Here is the minimal example:

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

part 'f.freezed.dart';

typedef MyTypedef = Function(AppLocalizations it);

@freezed
class Demo with _$Demo {

  factory Demo.test(MyTypedef myTypedef) = DemoTest;

}

AppLocalizations originates from the flutter_localizations package (lies in .dart_tool).

The generated code looks like this:

abstract class DemoTest implements Demo {
  factory DemoTest(dynamic Function(dynamic) myTypedef) = _$DemoTest;

  @override
  dynamic Function(dynamic) get myTypedef;
  @override
  @JsonKey(ignore: true)
  $DemoTestCopyWith<DemoTest> get copyWith =>
      throw _privateConstructorUsedError;
}

This is not a valid override, and therefore the app does not compile.

The interesting part, using it as just a parameter works perfectly fine:

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

part 'f.freezed.dart';

@freezed
class Demo with _$Demo {

  factory Demo.test(AppLocalizations appLocalizations) = DemoTest;

}

Generated code:

abstract class DemoTest implements Demo {
  factory DemoTest(AppLocalizations appLocalizations) = _$DemoTest;

  @override
  AppLocalizations get appLocalizations;
  @override
  @JsonKey(ignore: true)
  $DemoTestCopyWith<DemoTest> get copyWith =>
      throw _privateConstructorUsedError;
}

(Which is fine)

The use case for this is a typedef which allows a StateNotifier of mine to generate localized Strings for the UI to use like this:

state = MyErrorState(
  error: (localizations) => localizations.myError,
);

Sorry for the weird issue lol.

rrousselGit commented 2 years ago

I'm not quite sure what's happening here. Freezed isn't exactly doing anything special with functions. It's only doing a toString of what the analyzer sends