Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for TypeScript #8

Merged
merged 10 commits into from
Mar 3, 2019
Merged

Add support for TypeScript #8

merged 10 commits into from
Mar 3, 2019

Conversation

otofu-square
Copy link
Contributor

@otofu-square otofu-square commented Feb 28, 2019

Close #7

Introduce TypeScript type definitions 🎉

  • Add some packages to devDependencies(typescript, typings-tester, @types/react)
  • Add index.d.ts to define typings
  • Add test for index.d.ts with typings-tester


const ThemesContext = createContext(themes)

const useTheme = (initialTheme: InitialTheme = DARK) => {
Copy link
Contributor Author

@otofu-square otofu-square Feb 28, 2019

Choose a reason for hiding this comment

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

Add minimum typing tests with the example code in README.md.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not a big fan of that example, but I wanted something that used a few different hooks, so it became a little contrived. Happy for you to come up with something better if you want, or just keep it as is that's easier.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so it became a little contrived

I see.

Happy for you to come up with something better

I'll give it a try soon 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replace useTheme hook with useCounter here 3cb8f92.
Also fix type definitions because I just realized they are broken.

@otofu-square
Copy link
Contributor Author

@mpeyper
Please review this PR and let me know if you have any questions. thx!

@otofu-square
Copy link
Contributor Author

Created minimum TS project with react-hooks-testing-library: https://github.com/otofu-square/react-hooks-testing-library-sandbox

readonly rerender: (hookProps?: P) => void
}

export const testHook: typeof renderHook
Copy link
Member

Choose a reason for hiding this comment

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

nice

@mpeyper
Copy link
Member

mpeyper commented Feb 28, 2019

I'm reviewing this, but I'm far from a Typescript expert (I don't use it day to day, just created basic type definitions for some of my other libraries before, and not of them are as cool as what you've done here), so I'm sorry for any dumb questions. I'd also like it if someone that does use Typescript regularly could chip in and give me an indiation of whether the types here make sense.

index.d.ts Outdated
import { cleanup, act, RenderOptions, RenderResult } from 'react-testing-library'

export function renderHook<P extends any, T extends (...args: [P]) => any>(
callback: (_: P) => ReturnType<T>,
Copy link
Member

Choose a reason for hiding this comment

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

Where does ReturnType come from?

Copy link
Member

Choose a reason for hiding this comment

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

@mpeyper
Copy link
Member

mpeyper commented Mar 1, 2019

This looks great to me. Waaaaaay better than anything I could have done myself. As I said before, I'd love a TS user to put a comment on here with approval before merging.

Also can you please add yourself as a contributor to the README (by running this). I haven't got around to setting up a contributing document yet, so I don't blame you for not knowing this.

If anyone TS users do review this, please submit a PR adding yourself as a contributer as well.

@otofu-square
Copy link
Contributor Author

Also can you please add yourself as a contributor to the README

Oh, sorry! Will work on it soon.

@otofu-square
Copy link
Contributor Author

otofu-square commented Mar 1, 2019

Will work on it soon.

Done.

If anyone TS users do review this

Let me ask someone I know.

readonly rerender: (hookProps?: P) => void
}

export const testHook: typeof renderHook

Choose a reason for hiding this comment

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

It'll be unnecessary someday, but it 's so smart 👍

Copy link

@tatsushitoji tatsushitoji left a comment

Choose a reason for hiding this comment

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

LGTM, if this PR is the minimum typing or even if it does not 👍
I think that there is no problem to merge.

index.d.ts Outdated
@@ -0,0 +1,18 @@
import { cleanup, act, RenderOptions, RenderResult } from 'react-testing-library'

export function renderHook<P extends any, R extends any>(
Copy link
Member

Choose a reason for hiding this comment

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

what is the difference between renderHook<P extends any, R extends any> and renderHook<P, R>?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

rednerHook<P, R> is the same as renderHook<P extends Object, R extends Object>.
Maybe it's more simple to use <P, R> instead of <P extends any, R extends any> since P and R will be inferred by giving callback & initialProps.

index.d.ts Outdated Show resolved Hide resolved
@mpeyper
Copy link
Member

mpeyper commented Mar 1, 2019

How do the typings look when the callback returns void (i.e. a hook that does not actually return anything)? Is it worth having a test around that case? I'm not sure how often that will actually occur in the wild so I'm not too concerned, more curious than anything.

@otofu-square
Copy link
Contributor Author

otofu-square commented Mar 1, 2019

I'm not sure how often that will actually occur in the wild so I'm not too concerned, more curious than anything.

Currently the typing of result.current which returns from renderHook is void type in this case.
IMHO, I think result.current can be unnecessary in any case if hook returns void.

Is it worth having a test around that case?

Maybe it's worth to test that result.current has void type when hook returns void 🤔

index.d.ts Outdated Show resolved Hide resolved
current: R
}
readonly unmount: RenderResult['unmount']
readonly rerender: (hookProps?: P) => void
Copy link
Contributor

@danielkcz danielkcz Mar 2, 2019

Choose a reason for hiding this comment

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

Feels unnecessary to have ? here. If the P is inferred as undefined, it should be ok. Otherwise, it should be required to pass the props if there were some initially to avoid surprising results.

Suggested change
readonly rerender: (hookProps?: P) => void
readonly rerender: (hookProps: P) => void

Copy link
Contributor Author

@otofu-square otofu-square Mar 3, 2019

Choose a reason for hiding this comment

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

Looking at the implementation of the rerender function, it seems that hookProps.current is assigned as a default value. (hookProps.current is the same as initialProps)
https://github.com/mpeyper/react-hooks-testing-library/blob/f7cd61035d8fb08cbfac376a5a8da1780708a64e/src/index.js#L26

As long as I see this, we can call rerender function with no argument or initialProps.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, so it will use initialProps if none are passed. Makes sense I guess although it feels less explicit and might be confusing for tests.

Copy link
Member

Choose a reason for hiding this comment

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

Correct. Subsequent rerenders will use the previously supplied props until new props are supplied.

The idea is that the props don't change until the hook is rendered with new props, so hooks that use a conditional array (i.e. useEffect, useLayoutEffect, useMemo and useCallback) can be reliably tested.

@@ -26,6 +27,7 @@
"@babel/plugin-transform-modules-commonjs": "^7.2.0",
"@babel/preset-env": "^7.3.4",
"@babel/preset-react": "^7.0.0",
"@types/react": "^16.8.5",
Copy link
Contributor

@danielkcz danielkcz Mar 2, 2019

Choose a reason for hiding this comment

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

Where does it depend on React types actually? I don't see any reference to it.

Suggested change
"@types/react": "^16.8.5",

Copy link
Contributor Author

@otofu-square otofu-square Mar 3, 2019

Choose a reason for hiding this comment

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

@mpeyper
Copy link
Member

mpeyper commented Mar 3, 2019

Ok, I feel like all comments have either been addressed or explained so I'm going to merge this.

@FredyC, @tatsushitoji (and anyone else who may have contributed in some way to the PR), please open a PR adding yourself code review contributors by running npm run contributors:add and following the prompts.

@mpeyper mpeyper merged commit bce403f into testing-library:master Mar 3, 2019
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