More type-safe way to call a method on event target?

I have an input and I want to “commit” its value if a user presses Enter. That is, to blur the focus and do the same thing as if the input would lose the focus after pressing <TAB> or clicking outside. I came to the following:

    let handleKeyDown = event => {
      if event->ReactEvent.Keyboard.keyCode == 13 {
        (event->ReactEvent.Keyboard.target)["blur"]() // <- Unsafe :(
      }
    }

    let handleBlur = _ => {
      /* some commit code */
    }

    <input
      _type="number"
      onKeyDown=handleKeyDown
      onBlur=handleBlur
    />

What disturbs me is the contrast between:

if event->ReactEvent.Keyboard.keyCode == 13 {

which is very type safe, enforced to be a keyboard event (and not a MouseEvent, for example) and:

(event->ReactEvent.Keyboard.target)["blur"]()

which looks like a fall of the last hope. The blur might be there, or might be not. It might be a callable, or it might be not; nothing is type-checked.

The code does its job just fine but I’m feeling type-unsafe and hacky. Is there a more type-safe and robust way to express the same effect? Perhaps, an elegant bridge to Webapi.Dom.HtmlElement?

4 Likes

An answer to the elegant bridge request :

1 Like

In theory, the community could fork rescript-react and make it compatible with rescript-webapi. Or with an even more typesafe proposal by @yawaramin.

3 Likes

rescript-webapi lacks some Event bindings that are present in ReactEvent though. The best course of action will be bringing the missing bindings from ReactEvent to rescript-webapi, making it essentially the best way to interact with the DOM in a type-safe way, and then trying to convince the rescript-react maintainers to accept the PR with the Deprecation of ReactEvent in favor of rescript-webapi. I know they have a strong opinion about everyone should make their own bindings, but making everyone create bindings for such a ubiquitous thing as DOM is rather absurd. I guess if they insist on continuing shipping rescript-react with subpar DOM bindings that force you to write unsafe code the fork is more than justified.

Forking the repo might even be not the worst course of action, the repo looks abandoned (the last commit in rescript-react was more than a half a year ago)

1 Like

It’s not possible to write completely type safe bindings for the DOM because the DOM isn’t sound. There are type wedges and unsafe hacks all over rescript-webapi, if you aren’t using it with your eyes open it can and will lead to runtime errors.

The intent is not for everyone to write custom bindings, it’s… well I got into a big argument with the ReScript team about this a year ago. I’m not going to rehash it or speak for them. I chose to put my investment in the bindings I need, if they are useful to others that’s great.

As for extending the event bindings in rescript-webapi, we will happily accept contributions.

1 Like

I was also very surprised to see there are some methods that only have unsafe versions. I don’t understand why can’t they just handle the exception and return an option, for example.