Dart Flutter Union String types

3,329

Dart does not have such a feature yet. There has been some discussions about it but I can't remember if the feature are still considered or when it comes.

So for now we need to do what the language provides and make our own "solution". In my experience, what people most want is actually enums since the string value itself are not important after it is mapped.

Enums are also what comes closest to union string types since we have a finite amount of allowed stings which the compiler can verify we takes care of in e.g. switch-statements.

So we can do something like this if we want to make it a little fancy:

enum ThisThat { THIS, THAT }
ThisThat parseThisThat(String value) => ThisThat.values.firstWhere(
    (element) => element.toString() == 'ThisThat.${value.toUpperCase()}');
extension ThisThatValue on ThisThat {
  String get stringValue => toString().split('.')[1].toLowerCase();
}
void main() {
  ThisThat tt = parseThisThat('this');
  print(tt.stringValue); // this
  tt = parseThisThat('sheep'); // Unhandled exception: Bad state: No element
}

Personally, I would properly make it more explicit the parsing if the amount of allowed values are limited which also makes it easy to throw you own type of exception:

ThisThat parseThisThat(String value) {
  if (value == 'this') {
    return ThisThat.THIS;
  } else if (value == 'that') {
    return ThisThat.THAT;
  } else {
    throw Exception('$value is not a valid string value for ThisThat');
  }
}

Or using switch:

ThisThat parseThisThat(String value) {
  switch (value) {
    case 'this':
      return ThisThat.THIS;
    case 'that':
      return ThisThat.THAT;
    default:
      throw Exception('$value is not a valid string value for ThisThat');
  }
}

The purpose of the extension is so we can get the string value again. In Dart, the toString() on a enum value will e.g. return ThisThat.THIS. This is properly fine in most cases but if you want to convert it back you can add the extension method which in this case gives a stringValue property on the enum value.

(Should also note that it could be easier if the allowed string was not this since you cannot have a enum value with the name this since this is a keyword. But THIS is allowed so that is why my enum was upper cased. :)

Share:
3,329
Eric Grossman
Author by

Eric Grossman

Updated on December 26, 2022

Comments

  • Eric Grossman
    Eric Grossman 5 months

    In typescript if I want to make sure a variable is 'this' or 'that' I would do:

    type ThisThat = 'this'|'that'
    

    I could then use this type in another interface like :

    interface B{
       text: ThisThat;
    }
    

    How would I do this same thing in dart/flutter using classes? Or is there a different way to do it? I looked up dart enums and it seems that using String enums in dart isn't exactly straight-forward.