Dart uses a sound type system which means an expression always should evaluate to to the expression’s static type. However, dart also let us get away with annotating types to variables because of type inference.
My recommendation is always try to provide variables with types because type inference ends up using dynamic type when the analyzer doesn’t have enough information to infer a specific type.
Problem
The code below causes a type error because _saved.map
returns a list that evaluates to dynamic. It is because the entries inside _saved
does not provide enough information for type inference. Furthermore, according to the documentation, ListTile.divideTiles
requires Iterable<Widget>tiles
.
type 'MappedListIterable' is not a subtype of type 'Iterable'
// "tiles" evaluates to dynamic by type inference
class SavedWords extends StatelessWidget {
final _biggerFont = TextStyle(fontSize: 18.0);
@override
Widget build(BuildContext context) {
final _saved = Provider.of<Saved>(context).getSaved;
final tiles = _saved.map((WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
});
final divided = ListTile.divideTiles(
context: context,
tiles: tiles,
).toList();
return Scaffold(
appBar: AppBar(
title: Text('Saved Suggestions'),
),
body: divided.length > 0
? ListView(children: divided)
: Center(
child: Text('There is no saved item.'),
),
);
}
}
Solution
Since tiles
expect a list that has widget
entries, _saved.map
might as well define its return type to List<Widget>
.
final tiles = _saved.map<Widget>((WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
});
Thanks for reading.
Hope you enjoyed the article. If you have any question or opinion to share, feel free to write some comments.