rrousselGit / state_notifier

ValueNotifier, but outside Flutter and with some extra perks
MIT License
311 stars 28 forks source link

StateNotifierProvider stronger type inference for State objects #65

Closed pattobrien closed 2 years ago

pattobrien commented 2 years ago

Problem Description

When declaring a provider, it becomes rather tedious and somewhat illegible to explicitly define types for StateNotifierProvider.

For example, instead of being able to write:

final firstNameProvider = StateNotifierProvider((ref) => StringNotifier());  // State generic = Object?

we instead need to write:

final firstNameProvider = StateNotifierProvider<StringNotifier,String>((ref) => StringNotifier());

For context, the mid-complexity app that I've begun migrating fully to Riverpod (for all layers) has ~70 declared providers. In the context of such apps, it becomes especially tedious to explicitly define types for the reasons stated below:

Declaration Length

  1. When StateNotifier / State classes are long, dart's recommended lint rules of 80-character lines make the declarations annoying to type out and much more difficult to read:
final playlistConfigurationPageControllerProvider = StateNotifierProvider<
    PlaylistConfigurationPageController, PlaylistConfigurationPageState>(
  (ref) => PlaylistConfigurationPageController(
    practiceRepository: ref.watch(practiceRepositoryProvider),
  ),
);

Likelihood of Forgotten Generic Typing

  1. When types aren't explicitly required, it's possible that a developer originally forgets to include types, only until implementing the provider reference in the UI layer. This has caused me a good amount of back-and-forth between files to implement forgotten types.

Desired Solution

The desired solution is that the same line as above properly infers the State object of the StateNotifierProvider definition via the generic type of the StateNotifier in the return function (currently, only the StateNotifier type is inferred).

//  Generic Types inferred as: StateNotifier = StringNotifier, State = String
final firstNameProvider = StateNotifierProvider((ref) => StringNotifier()); 

class StringNotifier extends StateNotifier<String> {
  StringNotifier({String? initialValue}) : super(initialValue ?? '');

}

Possible Alternatives

I believe tooling (such as snippets or analyzer/lint rules) would help somewhat, but the DX would not be as great as if the types were inferred directly from the StateNotifierProvider class.

rrousselGit commented 2 years ago

Hello!

You're asking for something that's not possible. The issue is Dart itself. There's not much state_notifer/Riverpod can do about it.

pattobrien commented 2 years ago

@rrousselGit I figured that might be the case... Thanks for the quick feedback.