Типы строковых литералов (как в TypeScript) в Dart?

#typescript #dart

#typescript #dart

Вопрос:

Я начал использовать Dart благодаря Flutter, и мне очень нравится этот язык.

Я использовал TypeScript раньше, который предлагал некоторые действительно интересные функции, которые я раньше не видел, одна из них, которая мне особенно понравилась, — это строковые литеральные типы, которые выглядят примерно так

 type Easing = "ease-in" | "ease-out" | "ease-in-out";
function doSomething(easing: Easing) { /* do something */}
doSomething("ease-in");  // OK
doSomething("easy");  // ERROR
  

В Dart я нахожу использование enum s иногда неудобным, особенно при взаимодействии с реализациями плагинов для конкретной платформы. Я пропускаю строковые литеральные типы каждый раз, когда мне нужно добавить интерфейс Dart для Android static String или enum Android.

Одним из примеров этого может быть android_intent плагин (но это происходит гораздо чаще):

 void _createAlarm() {
  final AndroidIntent intent = const AndroidIntent(
    action: 'android.intent.action.SET_ALARM',
    arguments: <String, dynamic>{
      'android.intent.extra.alarm.DAYS': <int>[2, 3, 4, 5, 6],
      'android.intent.extra.alarm.HOUR': 21,
      'android.intent.extra.alarm.MINUTES': 30,
      'android.intent.extra.alarm.SKIP_UI': true,
      'android.intent.extra.alarm.MESSAGE': 'Create a Flutter app',
    },
  );
  intent.launch();
}
  

Есть ли способ в Dart иметь эти «волшебные строки», как в строковых литералах TypeScript?

Ответ №1:

Каждая enum константа создает Enum экземпляр, который имеет toString() метод, который будет возвращать строку с именем enum типа и именем константы. Например, учитывая:

 enum MyEnum {
  myConstant,
}
  

затем MyEnum.myConstant.toString() вернется "MyEnum.myConstant" . Хотя это не позволит вам легко создавать произвольные строки, вы могли бы сделать что-то вроде:

 enum alarm {
  DAYS,
  HOUR,
  MINUTES,
  SKIP_UI,
  MESSAGE,
}

void _createAlarm() {
  final arguments = <alarm, dynamic>{
    alarm.DAYS: <int>[2, 3, 4, 5, 6],
    alarm.HOUR: 21,
    alarm.MINUTES: 30,
    alarm.SKIP_UI: true,
    alarm.MESSAGE: 'Create a Flutter app',
  };

  final AndroidIntent intent = const AndroidIntent(
    action: 'android.intent.action.SET_ALARM',
    arguments: arguments.map((k, v) => MapEntry('android.intent.extra.$k', v)),
  );
  intent.launch();
}