-
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
"Infer this type" for explicit generic types. #3510
Comments
Today, you could do this with: |
The easy way to write this is to have each subtype implement class SomeModel extends ChangeNotifier {
final String name;
SomeModel(this.name);
R select<R>(R Function(SomeModel) selector) => selector(this);
} Then you don't need to infer the type of the model. If the argument is always the type itself, then Dart doesn't have self-types. abstract class ChangeNotifier<N extends ChangeNotifier<N>> {
R select<R>(R Function(N) selector) =>
selector(this as N); // Unsafe if used incorrectly
}
class SomeModel extends ChangeNotifier<SomeModel> {
final String name;
SomeModel(this.name);
}
void main() {
// Works both at type SomeModel and ChangeNotifier<SomeModel>
ChangeNotifier<SomeModel> notifier = SomeModel("Baba Yaga");
// Infers `m` to have type SomeModel, name to have type String.
var name = notifier.select((m) => m.name);
// The `name` is a `String`
print(name.substring(0, name.indexOf(' ')));
} Inferring partial type arguments isn't a bad idea. We can do it for all of them, we should be able to do it for some. notifier.select<SomeModel,>(...); // Trailing comma means an omitted type argument So you can do Or, we can allow curried type arguments: R select<M><R>(R Function(M) selector) => selector(this as M); so you can do Or optional type arguments: R select<M, [R]>(R Function(M) selector) => selector(this as M); and you can call as |
I still think #170 is a good overall proposal because it enables a more complete feature set. Example: var name = notifier.select<SomeModel, final Inferred>((m) => m.name);
var name = notifier.select<SomeModel, final _>((m) => m.name);
var name = notifier.select<SomeModel, _>((m) => m.name); // We could treat `_` as `final _`, `__` as `final __`, etc..
// This enables nice features like:
if (Inferred is num) // Inferred <= String
// Not related with this issue but with this proposal maybe we could get some syntax of this sort to check types:
// List<final T> list = [1,2,3];
// if (T <= num) // `is`
// if (T == num) // `exactly`
// if (T >= num) // `super`
// if (T < num) // `is` excluding `exactly`
// if (T > num) // `super` excluding `exactly` |
What I'm thinking is simple. In the case where a function or class has multiple generic parameters, we should be allowed to explicitly say that the type system should infer the other arguments on its own. For example:
I guess we can always just specify the type in the closure itself, but it might still prove useful in other constructs. For now, this is what I find myself using it most for.
The text was updated successfully, but these errors were encountered: