From 8af624afbe50926ee476cbad993b80da2ce07802 Mon Sep 17 00:00:00 2001 From: Jessica Date: Wed, 6 Feb 2019 19:07:43 +0900 Subject: [PATCH] Use contrivances to present something close to act()'s real return type Make it harder to accidentally use it in contexts where a Promise may be expected. --- types/react-dom/react-dom-tests.tsx | 5 +++++ types/react-dom/test-utils/index.d.ts | 11 ++++++++++- types/react-test-renderer/index.d.ts | 11 ++++++++++- .../react-test-renderer/react-test-renderer-tests.ts | 2 ++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/types/react-dom/react-dom-tests.tsx b/types/react-dom/react-dom-tests.tsx index e81c500f9c..46274e3ffd 100644 --- a/types/react-dom/react-dom-tests.tsx +++ b/types/react-dom/react-dom-tests.tsx @@ -191,5 +191,10 @@ describe('React dom test utils', () => { // $ExpectError ReactTestUtils.act(() => null); }); + it('returns a Promise-like that errors out on use', () => { + const result = ReactTestUtils.act(() => {}); + // $ExpectError + Promise.resolve(result); + }); }); }); diff --git a/types/react-dom/test-utils/index.d.ts b/types/react-dom/test-utils/index.d.ts index f1eae65df6..fb98181847 100644 --- a/types/react-dom/test-utils/index.d.ts +++ b/types/react-dom/test-utils/index.d.ts @@ -291,4 +291,13 @@ export function createRenderer(): ShallowRenderer; * @see https://reactjs.org/blog/2019/02/06/react-v16.8.0.html#testing-hooks */ // the "void | undefined" is here to forbid any sneaky "Promise" returns. -export function act(callback: () => void | undefined): void; +// the actual return value is always a "DebugPromiseLike", +// but having an "| {}" makes it harder to accidentally use. +export function act(callback: () => void | undefined): DebugPromiseLike | {}; + +// Intentionally doesn't extend PromiseLike. +// Ideally this should be as hard to accidentally use as possible. +interface DebugPromiseLike { + // the actual then() in here is 0-ary, but that doesn't count as a PromiseLike. + then(onfulfilled: (value: never) => never, onrejected: (reason: never) => never): never; +} diff --git a/types/react-test-renderer/index.d.ts b/types/react-test-renderer/index.d.ts index 040ec3a513..34ddb2502c 100644 --- a/types/react-test-renderer/index.d.ts +++ b/types/react-test-renderer/index.d.ts @@ -64,4 +64,13 @@ export function create(nextElement: ReactElement, options?: TestRendererOpt * @see https://reactjs.org/blog/2019/02/06/react-v16.8.0.html#testing-hooks */ // the "void | undefined" is here to forbid any sneaky "Promise" returns. -export function act(callback: () => void | undefined): void; +// the actual return value is always a "DebugPromiseLike", +// but having an "| {}" makes it harder to accidentally use. +export function act(callback: () => void | undefined): DebugPromiseLike | {}; + +// Intentionally doesn't extend PromiseLike. +// Ideally this should be as hard to accidentally use as possible. +interface DebugPromiseLike { + // the actual then() in here is 0-ary, but that doesn't count as a PromiseLike. + then(onfulfilled: (value: never) => never, onrejected: (reason: never) => never): never; +} diff --git a/types/react-test-renderer/react-test-renderer-tests.ts b/types/react-test-renderer/react-test-renderer-tests.ts index b7e23caf25..48d861cf62 100644 --- a/types/react-test-renderer/react-test-renderer-tests.ts +++ b/types/react-test-renderer/react-test-renderer-tests.ts @@ -73,3 +73,5 @@ act(() => {}); act(async () => {}); // $ExpectError act(() => null); +// $ExpectError +Promise.resolve(act(() => {}));