title: How to use generics with freezed sealed union objects?
body: <p>I have a Flutter class that uses <a href="https://pub.dev/packages/freezed" rel="nofollow noreferrer">Freezed</a> to create a sealed union that represents either data or an error:</p>
  <pre class="lang-dart prettyprint-override"><code>@freezed
  class DataOrError&lt;T, E&gt; with _$DataOrError {
    const factory DataOrError.loading() = Loading;
  
    const factory DataOrError.data(T data) = DataOrE&lt;T, E&gt;;
  
    const factory DataOrError.error(E error) = DOrError&lt;T, E&gt;;
  
    static DataOrError&lt;T, E&gt; fromEither&lt;T, E&gt;(Either&lt;E, T&gt; val) {
      final result = val.fold(
          (l) =&gt; DataOrError&lt;T, E&gt;.error(l), (r) =&gt; DataOrError&lt;T, E&gt;.data(r));
      return result;
    }
  }
  </code></pre>
  <p>I use riverpod so I have a riverpod <a href="https://riverpod.dev/docs/providers/state_notifier_provider/" rel="nofollow noreferrer">StateNotifier</a> that looks like:</p>
  <pre class="lang-dart prettyprint-override"><code>class RolesNotifier
      extends StateNotifier&lt;DataOrError&lt;List&lt;Role&gt;, RoleFailure&gt;&gt; {
    final Ref _ref;
    StreamSubscription? sub;
  
    RolesNotifier(Ref ref)
        : _ref = ref,
          super(const DataOrError.loading());
  
    /// Will run the fetch
    void fetch() {
          // fetch roles
          state = const DataOrError.loading();
          sub = _ref.read(firebaseRoleService).getRoles().listen((event) {
            state = DataOrError.fromEither&lt;List&lt;Role&gt;, RoleFailure&gt;(event);
          });
    }
  
  // ... this class has been shortened for simplicity.
  }
  
  final rolesProvider = StateNotifierProvider.autoDispose&lt;RolesNotifier,
      DataOrError&lt;List&lt;Role&gt;, RoleFailure&gt;&gt;((ref) {
    return RolesNotifier(ref);
  });
  </code></pre>
  <p>When I consume this provider; however, the types for DataOrError are gone:</p>
  <pre class="lang-dart prettyprint-override"><code>ref
    .read(rolesProvider)
    .when(loading: (){}, data: (d) {
    // d is dynamic type not List&lt;Role&gt;
          
    }, error: (e){});
  </code></pre>
  <p>For some reason both <code>d</code> and <code>e</code> are dynamic types and not <code>List&lt;Role&gt;</code> &amp; <code>RoleFailure</code> respectively. Everything appears to be typed correctly so why is this not working? I'm not sure if the error is with Freezed or Riverpod. I would like to avoid type casting (i.e. <code>d as List&lt;Role&gt;</code>) because that defeats the purpose of the generics.</p>