Search code examples
flutterdartlinter

Dart/Flutter linter rule: the type to index a map should be the key type of map?


For example, I have Map<int, int> m;. Then I can write down m['hello'] without any compile-time error, but of course, cannot find any element at runtime. I hope it will produce an error (or warning) at compile-time or lint time.

This is a big problem in many cases. For example, when I refactor Map<A, int> m into Map<B, int> m, I want to have compile-time errors for all accesses like m[some_var_of_type_A], instead of no compile-time errors and suddenly it explodes at runtime. As another example, the de-serialized JSON is of type Map<String, ...> but the key is actually a int. So it is tempting to do var userId=42; deserializedJson[userId] but only to find errors. Actually need to do deserializedJson[userId.toString()].

You know, dart's type system is so strong (even null safe!), and I really enjoy it since it catchs a LOT of bugs at compile-time. So I hope this problem can also be addressed at compile-time.

Thanks for any suggestions!


Solution

  • You can enable the collection_methods_unrelated_type lint to warn when doing lookups on a Map with arguments of the wrong type.

    Also see https://github.com/dart-lang/sdk/issues/37392, which requests a type-checked alternative to Map.operator []. In the meantime, Dart's extension mechanism allows anyone to easily add such an alternative themselves. For example, package:basics provides a type-checked Map.get extension.