typescript - Dart - Kako prisiliti da ključ mape bude sadržan u listi stringova


Recimo da imam sljedeću mapu koja ima key1 i key2:

Map<String, bool> _map = {
  'dog': true,
  'cat': true
};

Sada želim nametnuti Dartu da dopušta samo određene ključeve. U Typescriptu bih mogao napraviti nešto poput:

enum AvailableKeysEnum {
  Dog = 'dog',
  Cat = 'cat'
}

interface AvailableKeys {
  [key in AvailableKeysEnum]: boolean;
}

const availableKeys: AvailableKeys = {
  'dog': true, // Allowed
  'cat': true, // Allowed
  'dolphin': true // Denied
}

Moje pitanje je, kako mogu prisiliti Dart da dopušta samo određene ključeve?

Odgovor #1

Ako sam to pravilno razumio (ne znam TypeScript)

Dart nema ograničenja za ključeve, pa će biti potrebno proširiti Map i implementirati ta ograničenja. Evo koda za to.

import 'dart:collection';

class InvalidKeyError<K> extends Error {
  final Object key;
  final Set<K> keys;

  InvalidKeyError(this.key, this.keys);

  @override
  String toString() => "InvalidKeyError: $key not found in $keys";
}

class SpecialMap<K, V> extends MapMixin<K, V> {
  final Set<K> availableKeys;

  final Map<K, V> _map = {};

  SpecialMap(this.availableKeys) : assert(availableKeys != null);

  @override
  Iterable<K> get keys => _map.keys;

  @override
  void clear() => _map.clear();

  @override
  V remove(Object key) => _map.remove(key);

  @override
  V operator [](Object key) => availableKeys.contains(key)
      ? _map[key]
      : throw InvalidKeyError(key, availableKeys);

  @override
  operator []=(K key, V value) => availableKeys.contains(key)
      ? _map[key] = value
      : throw InvalidKeyError(key, availableKeys);
}

void main() {
  final availableKeys = {"cat", "dog"};
  final map = SpecialMap<String, bool>(availableKeys);

  map["cat"] = true;
  map["dog"] = true;
  map["anything else"] = false; //will throw InvalidKeyError at runtime
}

Iako to možete jednostavno ograničiti kroz tip ako želite. Nešto poput ovoga.

enum Keys {cat, dog}

void main(){
  final Map<Keys, bool> map = {};
  map[Keys.cat] = true;
  map[Keys.dog] = true;
  map["any other type"] = false; //complie time error
}

Povezani članci