Skip to content

Commit 48282c2

Browse files
authoredApr 23, 2024
fix: Ensure renderHook options extend options for render (#1308)
1 parent 067d0c6 commit 48282c2

File tree

2 files changed

+75
-7
lines changed

2 files changed

+75
-7
lines changed
 

‎types/index.d.ts

+56-7
Original file line numberDiff line numberDiff line change
@@ -179,19 +179,58 @@ export interface RenderHookResult<Result, Props> {
179179
unmount: () => void
180180
}
181181

182-
export interface RenderHookOptions<
182+
export interface BaseRenderHookOptions<
183183
Props,
184-
Q extends Queries = typeof queries,
185-
Container extends Element | DocumentFragment = HTMLElement,
186-
BaseElement extends Element | DocumentFragment = Container,
187-
> extends RenderOptions<Q, Container, BaseElement> {
184+
Q extends Queries,
185+
Container extends RendererableContainer | HydrateableContainer,
186+
BaseElement extends Element | DocumentFragment,
187+
> extends BaseRenderOptions<Q, Container, BaseElement> {
188188
/**
189189
* The argument passed to the renderHook callback. Can be useful if you plan
190190
* to use the rerender utility to change the values passed to your hook.
191191
*/
192192
initialProps?: Props
193193
}
194194

195+
export interface ClientRenderHookOptions<
196+
Props,
197+
Q extends Queries,
198+
Container extends Element | DocumentFragment,
199+
BaseElement extends Element | DocumentFragment = Container,
200+
> extends BaseRenderHookOptions<Props, Q, Container, BaseElement> {
201+
/**
202+
* If `hydrate` is set to `true`, then it will render with `ReactDOM.hydrate`. This may be useful if you are using server-side
203+
* rendering and use ReactDOM.hydrate to mount your components.
204+
*
205+
* @see https://testing-library.com/docs/react-testing-library/api/#hydrate)
206+
*/
207+
hydrate?: false | undefined
208+
}
209+
210+
export interface HydrateHookOptions<
211+
Props,
212+
Q extends Queries,
213+
Container extends Element | DocumentFragment,
214+
BaseElement extends Element | DocumentFragment = Container,
215+
> extends BaseRenderHookOptions<Props, Q, Container, BaseElement> {
216+
/**
217+
* If `hydrate` is set to `true`, then it will render with `ReactDOM.hydrate`. This may be useful if you are using server-side
218+
* rendering and use ReactDOM.hydrate to mount your components.
219+
*
220+
* @see https://testing-library.com/docs/react-testing-library/api/#hydrate)
221+
*/
222+
hydrate: true
223+
}
224+
225+
export type RenderHookOptions<
226+
Props,
227+
Q extends Queries = typeof queries,
228+
Container extends Element | DocumentFragment = HTMLElement,
229+
BaseElement extends Element | DocumentFragment = Container,
230+
> =
231+
| ClientRenderHookOptions<Props, Q, Container, BaseElement>
232+
| HydrateHookOptions<Props, Q, Container, BaseElement>
233+
195234
/**
196235
* Allows you to render a hook within a test React component without having to
197236
* create that component yourself.
@@ -200,11 +239,21 @@ export function renderHook<
200239
Result,
201240
Props,
202241
Q extends Queries = typeof queries,
203-
Container extends Element | DocumentFragment = HTMLElement,
242+
Container extends RendererableContainer = HTMLElement,
243+
BaseElement extends Element | DocumentFragment = Container,
244+
>(
245+
render: (initialProps: Props) => Result,
246+
options?: ClientRenderHookOptions<Props, Q, Container, BaseElement>,
247+
): RenderHookResult<Result, Props>
248+
export function renderHook<
249+
Result,
250+
Props,
251+
Q extends Queries = typeof queries,
252+
Container extends HydrateableContainer = HTMLElement,
204253
BaseElement extends Element | DocumentFragment = Container,
205254
>(
206255
render: (initialProps: Props) => Result,
207-
options?: RenderHookOptions<Props, Q, Container, BaseElement>,
256+
options?: HydrateHookOptions<Props, Q, Container, BaseElement>,
208257
): RenderHookResult<Result, Props>
209258

210259
/**

‎types/test.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export function testRenderOptions() {
4545
const options = {container}
4646
const {container: returnedContainer} = render(<button />, options)
4747
expectType<HTMLDivElement, typeof returnedContainer>(returnedContainer)
48+
49+
render(<div />, {wrapper: () => null})
4850
}
4951

5052
export function testSVGRenderOptions() {
@@ -191,6 +193,8 @@ export function testRenderHook() {
191193
rerender()
192194

193195
unmount()
196+
197+
renderHook(() => null, {wrapper: () => null})
194198
}
195199

196200
export function testRenderHookProps() {
@@ -215,6 +219,21 @@ export function testContainer() {
215219
// @ts-expect-error Only allowed for createRoot
216220
render('a', {container: document.createDocumentFragment(), hydrate: true})
217221
render('a', {container: document, hydrate: true})
222+
223+
renderHook(() => null, {container: document.createElement('div')})
224+
renderHook(() => null, {container: document.createDocumentFragment()})
225+
// @ts-expect-error Only allowed in React 19
226+
renderHook(() => null, {container: document})
227+
renderHook(() => null, {
228+
container: document.createElement('div'),
229+
hydrate: true,
230+
})
231+
// @ts-expect-error Only allowed for createRoot
232+
renderHook(() => null, {
233+
container: document.createDocumentFragment(),
234+
hydrate: true,
235+
})
236+
renderHook(() => null, {container: document, hydrate: true})
218237
}
219238

220239
/*

0 commit comments

Comments
 (0)
Failed to load comments.