Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String Literal Types (like in TypeScript) in Dart?

I started using Dart thanks to Flutter and I quite like the language.

I was using TypeScript before which offered some really cool features that I hadn't seen before, one I particularly liked is the string literal types that look something like this

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

In Dart, I find using enums sometimes inconvenient, especially when interacting with platform-specific implementations of plugins. I miss string literal types every time I need to add a Dart interface for Android's static Strings or enums.

One example of this would be from the android_intent plugin (but happens much more often):

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();
}

Is there a way in Dart to have these "magic strings" like in TypeScript's string literal types?

like image 406
Vince Varga Avatar asked Sep 12 '25 20:09

Vince Varga


1 Answers

Dart enum constants have a name extension that returns a string with the name of the constant. For example, given:

enum MyEnum {
  myConstant,
}

then MyEnum.myConstant.name will return 'myConstant'. Although this won't let you easily create arbitrary strings, you could do something like:

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: {
      for (var MapEntry(:key, :value) in arguments.entries)
        'android.intent.extra.alarm.${key.name}': value,
    },
  );

  intent.launch();
}
like image 100
jamesdlin Avatar answered Sep 15 '25 11:09

jamesdlin