Flow: How to import SyntheticEvent type?

Created on 1 Apr 2016  路  26Comments  路  Source: facebook/flow

How can I use this declaration: https://github.com/facebook/flow/blob/master/lib/react.js#L271-L287

I mark an event handler as receiving Event but it complain that it's actually SyntheticEvent but I see it's inside the react definitions, but how to use it? How do I import the type in my file?

Thanks

react

Most helpful comment

@benmvp you can get around not having to state it as a global by enabling some of the provided flow eslint rules.

Example:

{
  "parser": "babel-eslint",
  "plugins": [
    "flowtype"
  ],
  "rules": {
    "flowtype/define-flow-type": 1,
    "flowtype/use-flow-type": 1
  }
}

All 26 comments

You can declare the event type as SyntheticEvent.
Can you provide a code example?
You can try https://flow.org/try/ for that.

Ex:

// ...
onClick(e: SyntheticEvent<*>) {
  // ...
}
// ...

I think the confusion comes from understanding whether SyntheticEvent needs to be explicitly imported. My understanding is that it doesn't.

Rather than just annotating with FlowType I'd like to also include a runtime assert:

  searchInputChange: function (ev: SyntheticEvent) {
       assert.isTrue(ev instanceof SyntheticEvent);
  ...

But this cannot be done without importing SyntheticEvent and simply doing a:

import {SyntheticEvent} from 'react';

… fails.

I have the same issue, where do I import the SyntheticEvent from?

To create a runtime check you'll have to require it from the React module, but this not at all related to Flow now.
I don't have the answer to how to require it from React, but this issue can definitely be closed.

So instead of helping you'll answer anyways without giving the solution? Thats kinda weird ;)

I tried both

import { SyntheticEvent } from 'react'
import type { SyntheticEvent } from 'react'

which both result in an error that the named export doesn't exist although it's clearly there and also documented here. But again, for some reason that doesn't work (and yes, of course I'm using flow-typed).

So if you're kind enough to elude us with the answer, that would be really nice. Or just don't, because I obviously must be stupid for not knowing how to do that.

@arekkas to use it as a Flow type you don't have to import anything, it's available on the global context, AFAIK.
To use it to create a runtime check I don't know the answer, as I said previously, but this is not a Flow issue, so my opinion is that this issue should be closed.

Global context... not having to import anything... reminds me of Rails 馃槙

You can grab the SyntheticEvent constructor out of react-dom with require('react-dom/lib/SyntheticEvent') but I'm not sure that's a good idea as its an internal implementation detail and only the interface on event objects received by handlers is part of the public API.

It seems like this thread now provides a way to use the synthetic event type and also its runtime class, so I think that resolves the original issue and will close this. Let me know if there's more to discuss and I'm happy to reopen!

@asolove: If I try importing it as a type I run into this issue:

  6: import type { SyntheticEvent } from 'react-dom/lib/SyntheticEvent'
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ react-dom/lib/SyntheticEvent. Required module not found

I don't see react-dom in flow-typed, which makes sense due to these being types that are built into Flow. The motivation for my case is to make ESLint happy that it can find all of the identifiers in the file. To work around this I plan on adding all of the synthetic event types (13 by a quick count) on the globals whitelist for ESLint. Maybe we (or I) could put together an eslint preset that handles this so at least it's done once and the rest of us can just pull it in.

I'd be happy to leave a link here for the preset for others when that gets done.

Ah, that makes total sense, I didn鈥檛 think about that. Let me see if there鈥檚 a way to make this nicer within the flow react typings. If not, the eslint whitelist would also be s good plan.

I think we could just mark it as exported from the appropriate modules: https://github.com/facebook/flow/blob/master/lib/react.js#L257

Yep, I had this _exact_ problem and ended up adding SyntheticEvent to globals in my eslint config... 馃槥

I've been looking into putting together a PR for this, but each time I sync with Flow's master branch, I can't get the tests to pass (clean working tree). This ticket isn't about troubleshooting that, but... "in progress"?

@benmvp you can get around not having to state it as a global by enabling some of the provided flow eslint rules.

Example:

{
  "parser": "babel-eslint",
  "plugins": [
    "flowtype"
  ],
  "rules": {
    "flowtype/define-flow-type": 1,
    "flowtype/use-flow-type": 1
  }
}

Nice! Thanks @lasseborly!

Paste example from docs into Flow Try
And you have the error:

4: handleClick = (event: SyntheticEvent) => {
^ SyntheticEvent. Could not resolve name
4: handleClick = (event: SyntheticEvent) => {
^ HTMLButtonElement. Could not resolve name

Why?

P.S. if change version to 0.54.1 that works fine.

@cinic Flow playground doesn't have any builtin definitions.

SyntheticEvent and similar are global types. This probably can be changed in the future.

This probably can be closed.
/cc @vkurchatkin

This cause flow-runtime: Cannot resolve type: SyntheticInputEvent, If it's not properly exported, we can't get runtime check about it.

@fabiomcosta Link you've provided in the first comment leads to some unrelated content.

@alexeychikk just updated the link, it's now: https://flow.org/try/
But that is just to try out flow, nothing that would help with answering anything.

To use SyntheticEvent, you have to make sure https://flow.org/en/docs/config/options/#toc-no-flowlib-boolean is NOT set to true (false is the default) and then use it, there is no need to import it.

onClick = (event: SyntheticEvent<HTMLDivElement>) => {
  // ...
}
render() {
  return <div onClick={this.onClick} />
}

That "parameter" type (HTMLDivElement) is the type of the currentTarget property on the event object, people tend to use it with * (ie: SyntheticEvent<*>) when they are not sure what type currentTarget is or if currentTarget is not important to the event handler.

@fabiomcosta Can we fix FlowTry to have the builtin events declared?

@xixixao Interestingly I thought SyntheticEvent just worked on tryflow, but you're right, it doesn't.
Flow is an open source project, and I have no affiliation/obligation with it.

~It's still not working. Any solutions?~

UPD. Do not use SyntheticEvent, it's kind of abstraction. Use concrete event that satisfies your needs (ie SyntheticInputEvent, SyntheticMouseEvent).

@benmvp you can get around not having to state it as a global by enabling some of the provided flow eslint rules.

Example:

{
  "parser": "babel-eslint",
  "plugins": [
    "flowtype"
  ],
  "rules": {
    "flowtype/define-flow-type": 1,
    "flowtype/use-flow-type": 1
  }
}

Just to clarify newbies like me. Install eslint-plugin-flowtype and add above mentioned configurations to your .eslintrc.js

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mjj2000 picture mjj2000  路  3Comments

john-gold picture john-gold  路  3Comments

mmollaverdi picture mmollaverdi  路  3Comments

jamiebuilds picture jamiebuilds  路  3Comments

philikon picture philikon  路  3Comments