-
Notifications
You must be signed in to change notification settings - Fork 205
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
Type aliases: Typedefs for non-function types #65
Comments
Specification CL at https://dart-review.googlesource.com/c/sdk/+/81414. |
Feature specification proposal in this PR. |
Said feature specification landed as efdc2fa. |
PR created for the feature specification: One rule needs to be discussed, and the right thing to do is to say explicitly that no conclusion has been reached yet, with respect to that particular rule. |
I opened an issue for discussion of the question of using typedefs where classes are expected here. |
Said PR now landed. |
I think we need to update the spec to reflect the consensus on static method access. |
Landed #116 for that. |
I perused the spec, but I didn't see an obvious answer. How will the analyzer handle this? typedef IntList = List<int>;
IntList il = [1,2,3];
List<int> li = il; // potentially problematic Presumably that would be either a warning or an error, correct? What about this one (building on the code above)? void foo(IntList a) {}
List<int> b = [1,2,3];
foo(b); // potentially problematic In this case it isn't clear that |
|
But someone might change the definition of For example, the second call to package main
type MyInt int
func foo(a MyInt) {
println(a)
}
func main() {
var a MyInt = 0
foo(a)
var b int = 0
foo(b)
} |
That's not the same thing.
|
OK, that's really what I was curious about, I suppose. Thanks for clarifying! |
Would this include: typedef Test<T> = T Function();
typedef Test2 = Test<int>; ? Currently, this code does not compile, for no obvious reason. This is very limiting if we have anything more complex than |
The 'typedefs for non-function types' feature has not yet been implemented. It will happen, but the efforts to support other features (especially extension methods and non-nullable types) have left no resources available for this feature, so it's been postponed for a while. This means that we only have the kind of type alias that does not support non-function types: The grammar rule requires a That makes When this feature is implemented it will certainly be possible to have declarations like In any case, there should not be any particular limits on the complexity of the types that you define a given type alias to denote (neither with the current type alias feature, nor with the generalization that supports |
One question about this proposal: typedef IntList = List<int>;
extension on IntList {
doSometing();
}
var listOfItens = [1,2,3];
listOfItens.doSomething(); <-- It will be available? |
That's how it works already with extensions on functions, so likely. typedef VoidCallback = void Function();
extension on VoidCallback {
void foo() {}
}
void main() {
void Function() test = () {};
test.foo();
} |
Wow thats bad to hear 😢 |
But that's not a typedef anymore. That's a new type |
You're right, in other instances I do use Lists. But the way I tend to structure my data, everything is a class in a Map, or a list of such maps. So when I have a list, it usually ends up being passed into Also, am I the only one who does Json get json => { }; instead of Json toJson() => { }; It feels like every example I see has the latter, but I find getters to be so much cleaner. |
I guess it is common to set a local var to function calls while a getter is often called multiple times. |
You can also write something like that if you want to sacrifice code cleanness for 1ms performance improvement: Json _json;
Json get json => _json ??= <String, dynamic>{
...
}; It will cache json value in |
This feature is really near to completion now. A useful example could be a type alias that encapsulates a certain regularity in the use of an existing type: typedef MapToList<X> = Map<X, List<X>>;
void main() {
MapToList<int> m = {};
m[7] = [7];
m[8] = [2, 2, 2];
for (var x in m.keys) {
print('$x --> ${m[x]}');
}
} The point is that |
Thanks for all your hard work on this feature! Dart is special in that it pays so much attention to the little things. |
A wild commit appeared yesterday! It seems this will be released with Dart 2.13! |
Thanks for that! There's a great example in the CHANGELOG that is probably worth repeating -- deprecating classes. Let's say you have this: class BadName { /* some methods */ }
class OtherLibraries extends BadName { } So you want to rename class BetterName { /* some methods */ } // changed the original
@Deprecated("Use BetterName instead")
typedef BadName = BetterName; Now, all classes that extend |
Heh - can't keep anything from you guys. :) Just to manage expectations a bit... I haven't landed that patch yet, and there's still a non-zero (but hopefully small) chance that we won't make the branch cut date for 2.13. |
It does not change a lot when it will be released in the near future in my mind @leafpetersen :) Considering that the feature has been finished in most places (according to dart-lang/sdk#44951) and the fact that we should be aware of the standard release cycle, we should not have any different expectations in the first place ;) |
Dart more flexible typedefs may be coming soon in Dart 2.13 dart-lang/language#65
Why this issue stills open? 😁😁😁 |
You're right, done! |
Now that I actually want to use this feature (with JSON types, surprise surprise), I came across a problem: Where do I actually put the typedef? In my Flutter app, I have this file structure:
If I want classes @eernstg, thoughts? Are there any tests that happen to import aliases that I can pull inspiration from? |
I would probably do this. |
Okay, thanks for the recommendation, I'll do that. |
I have seen a lot of packages that would, in your scenario, have a |
Folks, this is all very interesting but Github bug comments are not the right space for it. |
I tried this feature in IntelliJ dart plugin , like it still not support. |
@fanthus, if you wish to report an issue with the IntelliJ plugin and non-function type aliases, please create an issue with 'area-intellij' and give more details. |
Can it be possible to get the name of typedef instead the underlying runtimeType in future? Since it's just an alias, I think it might be feasible with an extra field for variables with typedefs. typedef Meaning = int;
final Meaning life = 42;
void main() {
print(life.runtimeType); // prints 'int'
print(life.typedef); // prints 'Meaning'
} Why I would need this? typedef SessionID = String;
final provider = Provider<SessionID>(); runtimeType is |
@esenmx The way you describe it, it is a new type rather than an alias. I guess the problem is that |
Realizes #66, Feature specification
Sample typedef & usage:
Related issues: dart-lang/sdk#2626
The text was updated successfully, but these errors were encountered: