Strenglitteraltyper (som i TypeScript) i Dart?
Jeg begynte å bruke Dart takket være Flutter, og jeg liker språket ganske godt.
Jeg brukte TypeScript tidligere, som tilbød noen virkelig kule funksjoner som jeg ikke hadde sett før, en jeg spesielt likte er strengliteral-typene som ser omtrent slik ut
type Easing = "ease-in" | "ease-out" | "ease-in-out";
function doSomething(easing: Easing) { /* do something */}
doSomething("ease-in"); // OK
doSomething("easy"); // ERROR
I Dart synes jeg det noen ganger er upraktisk å bruke enums, spesielt når man samhandler med plattformspesifikke implementeringer av plugins. Jeg savner strengliteraltyper hver gang jeg trenger å legge til et Dart-grensesnitt for Androids static Strings eller enums.
Et eksempel på dette ville være fra android_intent-tillegget (men det skjer mye oftere):
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();
}
Finnes det en måte i Dart å ha disse «magiske strengene» som i TypeScripts streng-litteraltyper?
Svar #1
Dart enum-konstanter har en name-utvidelse som returnerer en streng med navnet på konstanten. For eksempel, gitt:
enum MyEnum {
myConstant,
}
da vil MyEnum.myConstant.name returnere 'myConstant'. Selv om dette ikke lar deg enkelt lage tilfeldige strenger, kan du gjøre noe som dette:
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();
}
