dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.21k stars 1.57k forks source link

[js inteorp] `asA` to correspond to `isA` #56957

Open parlough opened 1 day ago

parlough commented 1 day ago

With isA, I always have to end up casting to the desired type as well if I want to use members on the specified T type, as we can't rely on Dart's type promotion.

if (node.isA<HTMLAnchorElement>()) {
  final anchor = node as HTMLAnchorElement;
}

I've found myself wanting to add an extension method like:

extension on JSAny? {
  T? asA<T extends JSAny?>() {
    if (isA<T>()) {
      return this as T;
    }

    return null;
  }
}

So I can easily store the result without casting separately within the if.

if (node.asA<HTMLAnchorElement>() case final anchor?) {
  // ...
}

Yes I can add this myself, but I feel this is a pretty common case, so some version of it might be useful in dart:js_interop (if it makes sense). tryAsA could also work as a name if it's desired to distinguish from Dart's as which can throw.

srujzs commented 8 hours ago

Similar issue here: https://github.com/dart-lang/sdk/issues/54138

I avoided adding this because I was a little worried users might do both an isA and an asA e.g.

if (node.isA<HTMLAnchorElement>()) {
  var anchor = node.asA<HTMLAnchorElement>();
}

leading to duplicate interop type-checks. That being said, I do like the one-liner of node.asA<HTMLAnchorElement>() case final anchor?, so I'm torn. :)

Also, I actually would want this to throw if the type is wrong. Is there a reason we would not want this?