Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, String>' in type cast

I'm failing to cast a Map<String, dynamic> into a Map<String, Map<String, String>. What is the best way to do this?

Note that I'm using the advanced analysis options in my analysis_options.yaml:

analyzer:
  enable-experiment:
    - extension-methods
  strong-mode:
    implicit-casts: false
    implicit-dynamic: false

I tried

var de = Map<String, Map<String, String>>.from((json.decode(await rootBundle.loadString('lang/de.json'))) as Map<String, dynamic>);

and

var de = (json.decode(await rootBundle.loadString('lang/de.json')) as Map<String, dynamic>).cast<String, Map<String, String>>();

and

var de = Map.castFrom<String, dynamic, String, Map<String, String>>((json.decode(await rootBundle.loadString('lang/de.json'))) as Map<String, dynamic>);

All attempts raised the following runtime error: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, String>' in type cast

What is the best way to this? I think this can be done by iterating through the map but if these are very large, this is an expensive operation. Is there any way to cast them without iterating?

like image 517
DarkMath Avatar asked Oct 28 '25 01:10

DarkMath


1 Answers

I don't believe there is a way to cast to the appropriate type when dealing with nested data like this.

There was a similar discussion here about casting nested lists: https://github.com/dart-lang/language/issues/1574

I think iterating over the data in some fashion is the only thing you can do in this situation.

One possible solution:

final data = await rootBundle.loadString('lang/de.json');
final Map<String, Map<String, String>> de = {
  for (final entry in (json.decode(data) as Map).entries)
    entry.key as String: {
      for (final e in (entry.value as Map).entries)
        e.key as String: e.value as String,
    },
};

Since dart 3.3, one potential option that would have less overhead would be to create extension type wrappers on the json object.

for example:

import 'dart:convert';

extension type LanguageMap(Map<String, dynamic> json) {
  TranslationMap? operator [](String s) => json[s] as TranslationMap?;
}

extension type TranslationMap(Map<String, dynamic> json) {
  String? operator [](String s) => json[s] as String?;
}

void main() {
  Map<String, dynamic> json = jsonDecode(
          '{ "english": {"hello": "Hello"}, "spanish": {"hello": "Hola"} }')
      as Map<String, dynamic>;

  final lang = LanguageMap(json);
  final String? result = lang['spanish']?['hello'];
  print(result); // Hola
}
like image 87
mmcdon20 Avatar answered Oct 30 '25 18:10

mmcdon20



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!