I have an extension method:
extension When<T extends Object> on T {
T? when(bool Function(T self) predicate, {T Function(T self)? otherwise}) {
if (predicate(this)) return this;
return otherwise?.call(this);
}
}
It allows me to do some handling with inner variables and inner function results after testing them without the need for them to be saved in a variable.
Sometimes, when I wanted to use this with Widgets, it bothered me that I always need to cast it to Widget. So, I went and did the following extension, since it's more specific, the compiler uses it instead of the first.
extension WhenWidget<T extends Widget> on T {
Widget? when(bool Function(T self) predicate, {Widget Function(T self)? otherwise,}) {
if (predicate(this)) return this;
return otherwise?.call(this);
}
}
I asked myself, can I do something like this then?
extension When<R extends Object, T extends R> on T {
R? when(bool Function(T self) predicate, {R Function(T self)? otherwise}) {
if (predicate(this)) return this;
return otherwise?.call(this);
}
}
But this way all of my type inference goes away. What I wanted to do was create this extension in a way that knows how to handle super types. So, if I try and do:
final variable = 1.when((self) self.isEven, otherwise: (self) => self + 0.5)!;
The variable
would be num
and not Object
.
Edit
To be more precise, what I get is that the actual runtimeType
is in fact double
, but if you try and use .toInt()
or any inner method or whatever, it will warn you that you are trying to call that from a dynamic and that's not type-safe.