Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

React: Use specific event type for nativeEvent property - #15610

#15610
Merged
3 commits merged into
DefinitelyTyped:masterDefinitelyTyped/DefinitelyTyped:masterfrom
p-jackson:generic-native-eventp-jackson/DefinitelyTyped:generic-native-eventCopy head branch name to clipboard
Apr 17, 2017
Merged

React: Use specific event type for nativeEvent property#15610
3 commits merged into
DefinitelyTyped:masterDefinitelyTyped/DefinitelyTyped:masterfrom
p-jackson:generic-native-eventp-jackson/DefinitelyTyped:generic-native-eventCopy head branch name to clipboard

Conversation

@p-jackson

Copy link
Copy Markdown
Contributor

This change probably needs discussion.

This allows event handlers to fully use the ev.nativeEvent property without casting. But it does make the React.MouseEvent type slightly more complicated and is a breaking change for users using React.SyntheticEvent directly.

The case that led me to opening the PR is: I have a mouse event I'd like to access the movementX property on, but can see from React's synthetic mouse event docs that they don't support movementX, so I need to get it through the nativeEvent property.

Something I'd like feedback on is whether the way I'm getting access to the native event types from within the namespace is the best way. Is there something like ::GlobalType in Typescript?

Could be related to #6883, but I'm not thinking of the React Native case (I haven't used it before).

Please fill in this template.

  • Use a meaningful title for the pull request. Include the name of the package modified.

  • Test the change in your own code. (Compile and run.)

  • Follow the advice from the readme.

  • Avoid common mistakes.

  • Run npm run lint package-name (or tsc if no tslint.json is present).

  • Provide a URL to documentation or source code which provides context for the suggested changes:
    https://developer.mozilla.org/en-US/docs/Web/API/Event
    https://facebook.github.io/react/docs/events.html

  • Increase the version number in the header if appropriate.

  • If you are making substantial changes, consider adding a tslint.json containing { "extends": "../tslint.json" }.

@dt-bot

dt-bot commented Apr 4, 2017

Copy link
Copy Markdown
Member

types/react/index.d.ts

to authors (@pspeter3 @vsiao @johnnyreilly @bbenezech @pzavolinsky @digiguru AssureSign (account can't be detected) Microsoft (account can't be detected)). Could you review this PR?
👍 or 👎?

Checklist

  • pass the Travis CI test?

@p-jackson

Copy link
Copy Markdown
Contributor Author

My worries about breaking existing code were confirmed when my changes broke the build. A solution I've found is that in TypeScript 2.3 there should be a new feature for type parameter defaults (microsoft/TypeScript#13487), which means the existing interface can be extended.

I've tried the latest 2.3 dev build and pushed changes to show how that will work. I expect to come back to this PR once 2.3 is released (which might be around 18 April given their new release cadence?)

Comment thread types/react/index.d.ts

interface ClipboardEvent<T> extends SyntheticEvent<T> {
interface ClipboardEvent<T> extends SyntheticEvent<T, NativeClipboardEvent> {
clipboardData: DataTransfer;

@vsiao vsiao Apr 15, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to use a type parameter to do this. Try this:

interface ClipboardEvent<T> extends SyntheticEvent<T> {
    nativeEvent: NativeClipboardEvent;
}

Allows event handlers to fully use the `ev.nativeEvent` property without casting. But it does make the `React.MouseEvent` type slightly more complicated.
TypeScript 2.3 should be adding type parameter defaults, which allows the `nativeEvent` property to be made generic but without breaking existing code.
Overriding nativeEvent in this way maintains backwards compatibility and doesn't depend on bleeding-edge TypeScript features.
@p-jackson
p-jackson force-pushed the generic-native-event branch from 02795d2 to 7b9d4ea Compare April 16, 2017 08:55
@p-jackson

Copy link
Copy Markdown
Contributor Author

Thanks for the tip @vsiao! I was worried what would happen to users who try to update @types/react before they update TypeScript. This fixes that problem.

@ghost
ghost merged commit 940b36a into DefinitelyTyped:master Apr 17, 2017
@paranoidjk

Copy link
Copy Markdown
Contributor

This cause typescript compile error
https://travis-ci.org/ant-design/ant-design-mobile/jobs/222998838

antd-tools run compile
/Users/jiangkai/github/ant-design-mobile/node_modules/@types/react/index.d.ts(369,15): error TS2430: Interface 'TouchEvent<T>' incorrectly extends interface 'SyntheticEvent<T>'.
  Types of property 'nativeEvent' are incompatible.
    Type 'NativeTouchEvent' is not assignable to type 'Event'.
      Property 'bubbles' is missing in type 'NativeTouchEvent'.
/Users/jiangkai/github/ant-design-mobile/node_modules/@types/react/index.d.ts(427,46): error TS2344: Type 'TouchEvent<T>' does not satisfy the constraint 'SyntheticEvent<any>'.
  Types of property 'nativeEvent' are incompatible.
    Type 'NativeTouchEvent' is not assignable to type 'Event'.
[11:30:34] TypeScript: 2 semantic errors
[11:30:34] TypeScript: emit succeeded (with errors)

paranoidjk referenced this pull request in ant-design/ant-design-mobile Apr 18, 2017
paranoidjk added a commit to ant-design/ant-design-mobile that referenced this pull request Apr 18, 2017
@p-jackson

p-jackson commented Apr 18, 2017

Copy link
Copy Markdown
Contributor Author

@paranoidjk did the breakage occur because of React Native, or did this happen in web code? Do you think this will effect other React Native users?

I was hoping to get some "thumbs up" reviews before this was merged, hopefully from someone with React Native experience?

@paranoidjk

Copy link
Copy Markdown
Contributor

@p-jackson I guess it's because react-native, since https://github.com/ant-design/ant-design is pure web react components got no error, but https://github.com/ant-design/ant-design-mobile both have react and react-native components, which compile gets error.

@ghost

ghost commented Apr 18, 2017

Copy link
Copy Markdown

@paranoidjk Can you get a good repro for this? Just installing @types/react doesn't produce any error.

@bherila

bherila commented Apr 18, 2017

Copy link
Copy Markdown
Contributor

I have a repro @Andy-MS

ERROR in ...\node_modules\@types\react\index.d.ts
(369,15): error TS2430: Interface 'TouchEvent<T>' incorrectly extends interface 'SyntheticEvent<T>'.
  Types of property 'nativeEvent' are incompatible.
    Type 'NativeTouchEvent' is not assignable to type 'Event'.
      Property 'bubbles' is missing in type 'NativeTouchEvent'.

ERROR in ...\node_modules\@types\react\index.d.ts
(427,46): error TS2344: Type 'TouchEvent<T>' does not satisfy the constraint 'SyntheticEvent<any>'.
  Types of property 'nativeEvent' are incompatible.
    Type 'NativeTouchEvent' is not assignable to type 'Event'.

@ghost

ghost commented Apr 18, 2017

Copy link
Copy Markdown

I need steps that would allow me to reproduce it. Just installing @types/react doesn't cause any errors for me.

@bherila

bherila commented Apr 18, 2017

Copy link
Copy Markdown
Contributor

I tried also on top of https://github.com/ant-design/ant-design/ and it didn't repro. Any tips how one might be able to debug the conflicting Event type, perhaps? @Andy-MS

@bherila

bherila commented Apr 18, 2017

Copy link
Copy Markdown
Contributor

Interesting and possibly related, I'm now seeing:

ERROR in ...\node_modules\@types\react-native\index.d.ts
(3372,46): error TS2304: Cannot find name 'Map'.

So perhaps the issue really is with react-native. But, in that case I would also like us to fix that ;-)

@bherila

bherila commented Apr 18, 2017

Copy link
Copy Markdown
Contributor

Actually, the Map issue was fixed by changing target to es6 in tsconfig.json... the Event thing remains a mystery.

@ghost

ghost commented Apr 18, 2017

Copy link
Copy Markdown

So, the problem is it thinks NativeTouchEvent isn't assignable to Event.
But NativeTouchEvent = TouchEvent, TouchEvent extends UIEvent, and UIEvent extends Event.
Maybe it has to do with an older version of lib.dom.d.ts?

@bherila

bherila commented Apr 18, 2017

Copy link
Copy Markdown
Contributor

Yep that did it! Thanks @Andy-MS

@paranoidjk try upgrading your typescript package to the latest.

@bherila

bherila commented Apr 19, 2017

Copy link
Copy Markdown
Contributor

@Andy-MS with latest typescript et. al., now actually having this with react-native

../node_modules/@types/react/index.d.ts(369,15): error TS2430: Interface 'TouchEvent<T>' incorrectly extends interface 'SyntheticEvent<T>'.
  Types of property 'nativeEvent' are incompatible.
    Type 'NativeTouchEvent' is not assignable to type 'Event'.
      Property 'bubbles' is missing in type 'NativeTouchEvent'.
../node_modules/@types/react/index.d.ts(427,46): error TS2344: Type 'TouchEvent<T>' does not satisfy the constraint 'SyntheticEvent<any>'.
  Types of property 'nativeEvent' are incompatible.
    Type 'NativeTouchEvent' is not assignable to type 'Event'.

Would this be a problem with the React typings or any other pointers?

@ghost

ghost commented Apr 19, 2017

Copy link
Copy Markdown

@bherila That looks like the same error as before. Check the definition of NativeTouchEvent -- it should eventually extend Event.

@bherila

bherila commented Apr 19, 2017

Copy link
Copy Markdown
Contributor

This time, the solution was to upgrade @types/react-native to the latest 😎

Thanks @Andy-MS !!

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.