#typescript #dart
#typescript #dart
Вопрос:
Допустим, у меня есть следующая карта, которая имеет key1
и key2
:
Map<String, bool> _map = {
'dog': true,
'cat': true
};
Теперь я хочу принудительно использовать Dart, чтобы разрешить только определенный из ключей. В Typescript я мог бы сделать что-то вроде:
enum AvailableKeysEnum {
Dog = 'dog',
Cat = 'cat'
}
interface AvailableKeys {
[key in AvailableKeysEnum]: boolean;
}
const availableKeys: AvailableKeys = {
'dog': true, // Allowed
'cat': true, // Allowed
'dolphin': true // Denied
}
Мой вопрос в том, как я могу заставить Dart разрешить только определенные ключи?
Комментарии:
1. На самом деле нет способа сделать это в Dart (пока), за исключением, возможно, создания пользовательской реализации карты, что не слишком сложно (используя api.dartlang.org/stable/2.2.0/dart-collection /… ) но, вероятно, все равно не стоит.
2. Dart и Typescript — очень разные языки. Typescript имеет структурную систему типов. Это позволяет использовать такие функции в Typescript. Система структурных типов (или система типов на основе свойств) — это основной класс систем типов, в котором совместимость типов и эквивалентность определяются фактической структурой или определением типа, а не другими характеристиками, такими как его имя или место объявления.
Ответ №1:
Если я правильно понял (я не знаю TypeScript)
У Dart нет ключевых ограничений, поэтому придется расширить карту и реализовать эти ограничения. Вот код для этого.
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
}
Хотя вы можете просто ограничить через type, если хотите. Что-то вроде этого.
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
}
Комментарии:
1. отметьте ansert как правильное решение, пожалуйста, если это то, что вы искали.