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
}
