-
Notifications
You must be signed in to change notification settings - Fork 214
Union types, like in typescript #2711
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
If we generalize this feature a little, it would seem that it is a way to define a "subset type":
SubtypingThe subset type is probably going to be a subtype of Should the If we don't make it as subtype of If we make If we make I'd go for being a subtype. Then it's also clear that you can use any member of the supertype on every value. Subtype checkingCan you do If you cannot, then things get weird. You probably cannot have a The alternative is to not reify the type at runtime, and just erase it to the shared supertype. At that point, there is no longer any way to ensure that another string doesn't get "cast" to I'd recommend reifying the type, so it exists at runtime too. Other ponderingsAn This feature may be useful for some things, but I'm not sure replacing normal enums with string constants is the use-case that sells it to me. |
@lrhn Not 100% about this issue, but a "sub-problem". Could Dart ever have "literal types" (more concrete sub-type of a collective type) so developers could express a more correct API? With unions this might be useful. Some examples (horrendous syntax that might have grammar conflicts):
|
An enum type does have this nature: It is a statically known, finite set of objects. You can't subset them in the traditional sense, but you can use type arguments to do so: abstract class All {}
abstract class SomeA implements All {}
abstract class SomeB implements All {}
abstract class SomeOverlap implements SomeA, SomeB {}
enum E<X extends All> {
a<SomeA>(1),
b<SomeB>(2),
c<SomeOverlap>(3);
final int i;
const E(this.i);
} This means that You can use fields on the enum declaration in order to turn those sets of enum values into sets of other kinds of values. In the example above, Of course, this might look like an overly verbose and indirect exercise, but if you really need this typing structure then the technique where you are using an enum type is one possibility that should at least be on the radar. |
There are some differences between using This might avoid "dumb" enums from multiple libraries that can't be reused like: enum Answer {
Yes,
No
} Another question I have @eernstg, how would you extend a Enum, like enum DiceRoll {
One(1),
Two(2),
Three(3),
Four(4),
Five(5),
Six(6),
final int i;
const DiceRoll (this.i);
}
enum 8SidedDiceRoll extends DiceRoll {
Seven(7),
Eight(8),
const 8SidedDiceRoll (super.i);
}
|
Certainly, usages would be quite different. It's only relevant if you really need that typing structure, and you are willing to pay the syntax that it takes to get it.
You cannot extend an enum type. That's exactly the reason why I wasn't modeling subsets of a given finite set of values by declaring several enum types with a subtype relationship among them: That won't happen, because it is crucial for enum types that they are at the bottom of the subtype hierarchy (except for But you can use a type argument to organize the values of a given enum type into subsets, and that graph can be tailored to any DAG you might want (that is, it can model all possible subset relationships). This is what I did in the example here, based on the type hierarchy I didn't say it was convenient. Just possible. 😸 |
Enums are great for some cases. Here I am talking about literal unions types. For example making a http request basically require an url and a method (get, post, put etc.). Now I can achieve this by creating an enum enum RequestType { get, post, put, patch, delete } and then call the method final res = await Request(url, RequestType.get).call();
// Just for showing the case, nothing ingenious Now instead of creating the enum, It would be easy if I can write the above code like this final res = await Request(url, "get").call(); where "get" is a union type ("get", "post", "patch"), with auto-completion and without any other string value. Then we don't need to create an enum ( a TYPE) for this simple job. |
Dart is great, and it is also statically typed (sometimes not convenient). For example, why enums are not always good for a simple list of options like
This will also help library developers to reduce the types, so they don't conflict with types in other libraries.
The text was updated successfully, but these errors were encountered: