Dart 在回调函数上指定通用参数类型的正确方法

Dart correct way to specify generic argument type on callback function

我遇到了一个奇怪的错误,class 与此类似:

class UpdatableListPage<T> extends ConsumerStatefulWidget {
  final StateNotifierProvider<UpdatableNotifier, List<T>> provider;
  final Widget Function(T t) callbackWidget;

[...]

  @override
  _UpdatableListPageState<T> createState() => _UpdatableListPageState<T>();
}


class _UpdatableListPageState<T> extends ConsumerState<UpdatableListPage> {

 @override
  Widget build(BuildContext context) {
    // Here the IDE said modelList is dynamic
    var modelList = ref.watch(widget.provider);
    [...]
    ListView(
                key: _refreshKey,
                shrinkWrap: true,
                scrollDirection: widget.scrollDirection,
                children: [
                  for (final product in modelList as List<T>) widget.callbackWidget.call(product),
              ],

  }

}

我将函数称为:

UpdatableListPage<RsMsgMetaData>(
          userPostsProvider,
          callbackWidget:  (t) => PostTeaserCard(t,),
        ),

其中 PostTeaserCard 是接收 RsMsgMetaData 对象作为参数的有状态 Widget。

IDE 说一切正常,但在 运行 时,我收到以下错误:

type '(RsMsgMetaData) => PostTeaserCard' is not a subtype of type '(dynamic) => Widget'`

好像callbackWidget充当了(dynamic) => Widget函数,但无论如何...这个函数应该与匿名函数的函数签名兼容吧?

我不知道这是怎么回事...

您写道:

class _UpdatableListPageState<T> extends ConsumerState<UpdatableListPage> {

相当于:

class _UpdatableListPageState<T> extends ConsumerState<UpdatableListPage<dynamic>> {

因此,_UpdatableListPageState<T>.widget.callbackWidget的类型是Widget Function(dynamic t)。您不能为 Widget Function(dynamic) 传递 PostTeaserCard Function(RsMsgMetaData),因为后者可以使用任何参数调用,但您实际传递的函数只能使用 RsMsgMetaData 参数调用。

要解决此问题,请修复您的 _UpdatableListPageState class 声明以避免隐式使用 dynamic 并完全依赖 T:

class _UpdatableListPageState<T> extends ConsumerState<UpdatableListPage<T>> {

这可能会将 modelList 的类型修复为 List<T> 而不是 List<dynamic>

在您的 analysis_options.yaml 中启用 strict-raw-types 检查应该有助于在将来捕获此类错误。