See this answer for the different ways to declare data types and their tradeoffs. Are you creating the events yourself or are you wrapping DOM events? If you are wrapping I'd suggest to use an EmptyDataDecl. That would mean that you don't have constructors for each kind of event but you can add functions that check that type for you. If you create your own events it makes more sense to use a normal data declaration with constructors.
When wrapping DOM events you'd then end up with:
data Event
pageX :: Event -> Fay Int
pageX = ffi "%1['pageX']"
Fay has the Nullable type to deal with nullable values:
getElementById :: String -> Nullable Element
getElementById = ffi "document['getElementById'](%1)"
This is described in more detail on the wiki