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
检查应该有助于在将来捕获此类错误。
我遇到了一个奇怪的错误,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
检查应该有助于在将来捕获此类错误。