skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER

    As I've asked in an issue. There is no way for me to do what I want (at the moment). If you want more information, you can look here, I'm going to follow this issue as suggested in the comment linked before, so that when this new feature releases I'm aware. Thank you for the responses!


  2. Please replace this with following signature and usage

    void main() {
      final variable = 1.when<num, int>(
        (self) => self.isEven,
        otherwise: (self) => self + 0.5,
      );
    
      print(variable?.toInt());
    }
    
    extension When on dynamic {
      R? when<R, T extends R>(bool Function(T self) predicate,
          {R Function(T self)? otherwise}) {
        if (predicate(this)) return this;
        return otherwise?.call(this);
      }
    }
    

    Output: 1

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search