From 0c1ac2f09c0840c8b8d6c7e370402f5127cf80ae Mon Sep 17 00:00:00 2001 From: jongwooo Date: Tue, 22 Mar 2022 22:01:46 -0700 Subject: [PATCH 1/2] fix: Correct typo in no-fb-only.js (#1680) Summary: I found a typo in [no-fb-only.js](https://github.com/facebookexperimental/Recoil/blob/main/eslint-rules/no-fb-only.js) and corrected it. Pull Request resolved: https://github.com/facebookexperimental/Recoil/pull/1680 Differential Revision: D35053199 Pulled By: drarmstr fbshipit-source-id: 888ca286c142a0db9946e9332ca3758ae3ccded4 --- eslint-rules/no-fb-only.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eslint-rules/no-fb-only.js b/eslint-rules/no-fb-only.js index 86815b170..3e0ddded9 100644 --- a/eslint-rules/no-fb-only.js +++ b/eslint-rules/no-fb-only.js @@ -48,7 +48,7 @@ module.exports = { if (match) { context.report({ message: - `Usage of "${descriptor}". Please consider depenedncy injecting this condition ` + + `Usage of "${descriptor}". Please consider dependency injecting this condition ` + `instead. See "${__filename}" for more details`, loc: { start: {line: lineNumber + 1, column: 0}, From 91c71703d781f71d98507c794c75c3e25382e9c5 Mon Sep 17 00:00:00 2001 From: Douglas Armstrong Date: Tue, 22 Mar 2022 22:02:12 -0700 Subject: [PATCH 2/2] Typing fixes for 0.7 Summary: Some fix-ups for TypeScript and Flow typings for 0.7 Differential Revision: D35070577 fbshipit-source-id: 998c248fd9fb17ce4871a705bf71a87fec1a1b42 --- .../recoil/recoil_values/Recoil_atomFamily.js | 9 ++++-- .../__tests__/Recoil_atomFamily-test.js | 32 +++++++++++++++++++ typescript/index.d.ts | 4 +-- typescript/tests.ts | 7 ++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/packages/recoil/recoil_values/Recoil_atomFamily.js b/packages/recoil/recoil_values/Recoil_atomFamily.js index a35b2b1af..0f8c9a77d 100644 --- a/packages/recoil/recoil_values/Recoil_atomFamily.js +++ b/packages/recoil/recoil_values/Recoil_atomFamily.js @@ -63,7 +63,12 @@ export type AtomFamilyOptions = | Loadable | WrappedValue | T - | (P => T | RecoilValue | Promise), + | (P => + | T + | RecoilValue + | Promise + | Loadable + | WrappedValue), }> | AtomFamilyOptionsWithoutDefault; @@ -118,7 +123,7 @@ function atomFamily( | Loadable | WrappedValue | T - | (P => T | RecoilValue | Promise) = + | (P => T | RecoilValue | Promise | Loadable | WrappedValue) = 'default' in options ? // $FlowIssue[prop-missing] No way to refine in Flow that property is not defined // $FlowIssue[incompatible-type] No way to refine in Flow that property is not defined diff --git a/packages/recoil/recoil_values/__tests__/Recoil_atomFamily-test.js b/packages/recoil/recoil_values/__tests__/Recoil_atomFamily-test.js index a7cb58fe9..e2a7215b3 100644 --- a/packages/recoil/recoil_values/__tests__/Recoil_atomFamily-test.js +++ b/packages/recoil/recoil_values/__tests__/Recoil_atomFamily-test.js @@ -39,6 +39,7 @@ let store: Store, atom, atomFamily, selectorFamily, + RecoilLoadable, pAtom; const testRecoil = getRecoilTestFn(() => { @@ -72,6 +73,7 @@ const testRecoil = getRecoilTestFn(() => { atom = require('../Recoil_atom'); atomFamily = require('../Recoil_atomFamily'); selectorFamily = require('../Recoil_selectorFamily'); + ({RecoilLoadable} = require('../../adt/Recoil_Loadable')); store = makeStore(); @@ -151,6 +153,36 @@ describe('Default', () => { expect(get(paramDefaultAtom({num: 1}))).toBe(3); expect(get(paramDefaultAtom({num: 2}))).toBe(2); }); + + testRecoil('Parameterized async default', async () => { + const paramDefaultAtom = atomFamily({ + key: 'parameterized async default', + default: ({num}) => + num === 1 ? Promise.reject(num) : Promise.resolve(num), + }); + await expect(get(paramDefaultAtom({num: 1}))).rejects.toBe(1); + await expect(get(paramDefaultAtom({num: 2}))).resolves.toBe(2); + set(paramDefaultAtom({num: 1}), 3); + expect(get(paramDefaultAtom({num: 1}))).toBe(3); + expect(get(paramDefaultAtom({num: 2}))).toBe(2); + }); + + testRecoil('Parameterized loadable default', async () => { + const paramDefaultAtom = atomFamily({ + key: 'parameterized loadable default', + default: ({num}) => + num === 1 ? RecoilLoadable.error(num) : RecoilLoadable.of(num), + }); + expect(getLoadable(paramDefaultAtom({num: 1})).state).toBe('hasError'); + expect(getLoadable(paramDefaultAtom({num: 1})).contents).toBe(1); + expect(getLoadable(paramDefaultAtom({num: 2})).state).toBe('hasValue'); + expect(getLoadable(paramDefaultAtom({num: 2})).contents).toBe(2); + set(paramDefaultAtom({num: 1}), 3); + expect(getLoadable(paramDefaultAtom({num: 1})).state).toBe('hasValue'); + expect(getLoadable(paramDefaultAtom({num: 1})).contents).toBe(3); + expect(getLoadable(paramDefaultAtom({num: 2})).state).toBe('hasValue'); + expect(getLoadable(paramDefaultAtom({num: 2})).contents).toBe(2); + }); }); testRecoil('Works with date as parameter', () => { diff --git a/typescript/index.d.ts b/typescript/index.d.ts index aa86ba601..567431591 100644 --- a/typescript/index.d.ts +++ b/typescript/index.d.ts @@ -411,7 +411,7 @@ interface AtomFamilyOptionsWithoutDefault { | Loadable | WrappedValue | T - | ((param: P) => T | RecoilValue | Promise); + | ((param: P) => T | RecoilValue | Promise | Loadable | WrappedValue); } export type AtomFamilyOptions = | AtomFamilyOptionsWithDefault @@ -440,7 +440,7 @@ interface AtomFamilyOptionsWithoutDefault { get: (param: P) => (opts: { get: GetRecoilValue, getCallback: GetCallback, - }) => Promise | RecoilValue | T; + }) => Promise | Loadable | WrappedValue | RecoilValue | T; set: ( param: P, ) => ( diff --git a/typescript/tests.ts b/typescript/tests.ts index 31d82c63a..4fc55dcd0 100644 --- a/typescript/tests.ts +++ b/typescript/tests.ts @@ -426,6 +426,13 @@ isRecoilValue(mySelector1); // eslint-disable-next-line @typescript-eslint/no-unused-vars const myAtomFamilyWithoutDefault: (number: number) => RecoilState = atomFamily({key: 'MyAtomFamilyWithoutDefault'}); + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const myAsyncAtomFamily: (number: number) => RecoilState = + atomFamily({ + key: 'MyAsyncAtomFamily', + default: (param: number) => Promise.resolve(param), + }); } /**