Dart:Map.update错误“未捕获的错误:TypeError:类型'(dynamic)=> num'不是类型'(String)=> String'的子类型”

时间:2020-05-21 14:49:33

标签: dart

我有一个地图列表地图作为一组数据(dataMap),并希望使用Map.update方法进行如下转换。这捕获到错误:Uncaught Error: TypeError: Closure 'main__convertIdFromStringToDocRef_closure': type '(dynamic) => num' is not a subtype of type '(String) => String'。我应该对Map.update有所误解,但不确定是什么...您能教我吗?

void main() {
  num _convertStringToNum(dynamic str, String collection) {
    if (str is String) { return num.tryParse(str); }
    if (str is num) { return str; }
    return null;
  }

  Map<String, dynamic> _convertIdFromStringToNum(Map<String, dynamic> map, String collection) {
    map.update('id', (mapId) => _convertStringToNum(mapId, collection));
    return map;
  }

  Map<String, dynamic> dataMap = {
    'types': [
      {
        'id': '123',
        'name': 'foo',
      },
      {
        'id': '234',
        'name': 'bar',
      }
    ],
  };

  dataMap.update('types', (types) {
    if (!(types is List<Map<String, dynamic>>)) { return null; }
    types.map((Map<String, dynamic> type) => _convertIdFromStringToNum(type, 'types')).toList();
    return types;
  });
}

此代码可以在DartPad上运行。

2 个答案:

答案 0 :(得分:1)

我也遇到了你的奇怪问题。

好像地图条目是用String初始化的,就不能修改为num

Map<String, dynamic> item = {
 "id": "123",
 "name": "TEST"
};

// this throws exception that `item['id']` has `String` value and we are trying to replace it with `num`
item['id'] = num.tryParse(item['id']); 

我找到了解决方法,方法是使用构造函数创建自定义类,该构造函数将输入转换为必要的字段类型:

class Type {
  num id;
  String name;

  num convertToNum(dynamic input) {
    switch (input.runtimeType) {
      case int: break;
      case num: break;
      case String: return num.tryParse(input); break;
      default: return null;
    }
    return input;
  }

  Type(id, name) {
    this.id = convertToNum(id);
    this.name = name;
  }

  static fromMap(Map map) {
    return Type(map['id'], map['name']); 
  }

  Map toMap() {
    return {
      "id": this.id,
      "name": this.name
    };
  }
}

并在使用.map迭代列表的同时,我正在创建Type的实例并调用toMap方法,该方法返回唯一的对象。

void main() {
  Map<String, dynamic> dataMap = {
    'types': [
      {
        'id': 111,
        'name': 'foo',
      },
      {
        'id': '123',
        'name': 'foo',
      },
      {
        'id': '234',
        'name': 'bar',
      }
    ],
  };

  dataMap['types'] = (dataMap['types'] is List<Map>)
      ? dataMap['types'].map((type) => Type.fromMap(type).toMap())
      : null;

  print(dataMap);
}

答案 1 :(得分:0)

我自己找到了解决方案。 (但在真正的原因上仍然有不清楚的地方……)

问题出在.map(MapEntry<K2, V2> f(K key, V value))方法上。该方法的参数是一个函数MapEntry<K2, V2> f(K key, V value),正如我在其Map<String, dynamic>上的代码key中所描述的那样,但实际上它是JsLinkedHashMap<String, String>(值是{{ 1}})。当我尝试通过函数String中的map.update('id', (mapId) => _convertStringToNum(mapId, collection));分配非字符串值时,它将引发异常。

因此,我将代码更改如下。我创建了一个新的_convertIdFromStringToNumMap<String, dynamic>),然后对其进行newMap

.update()