Skip to content

Commit

Permalink
Typing fixes for 0.7 (#1690)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #1690

Some fix-ups for TypeScript and Flow typings for 0.7

Reviewed By: mondaychen

Differential Revision: D35070577

fbshipit-source-id: 2cbd3fcb585aa40e3fd218f60d8e291a4d4202e4
  • Loading branch information
drarmstr authored and facebook-github-bot committed Mar 24, 2022
1 parent 252e1f4 commit d922baa
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 6 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Expand Up @@ -3,7 +3,7 @@
## UPCOMING
**_Add new changes here as they land_**

## 0.7 (2022-03-23)
## 0.7 (2022-03-25)

### New Features
- The `default` value is now optional for `atom()` and `atomFamily()`. If not provided the atom will initialize to a pending state. (#1639)
Expand All @@ -19,9 +19,9 @@
- Automatically retain snapshots for the duration of async callbacks. (#1632)
- Optimization for more selector dependencies. 2x improvement with 100 dependencies, 4x with 1,000, and now able to support 10,000+. (#1651, #1515, #914)
- Better error reporting when selectors provide inconsistent results (#1696)
- Avoid spurious console errors from effects when calling `setSelf()` from `onSet()` handlers. (#1589, #1582)

### Fixes
- Avoid spurious console errors from effects when calling `setSelf()` from `onSet()` handlers. (#1589, #1582)
- Freezing user values in dev mode now works in JS environments without the `Window` interface. (#1571)

## 0.6.1 (2022-01-29)
Expand Down
9 changes: 7 additions & 2 deletions packages/recoil/recoil_values/Recoil_atomFamily.js
Expand Up @@ -63,7 +63,12 @@ export type AtomFamilyOptions<T, P: Parameter> =
| Loadable<T>
| WrappedValue<T>
| T
| (P => T | RecoilValue<T> | Promise<T>),
| (P =>
| T
| RecoilValue<T>
| Promise<T>
| Loadable<T>
| WrappedValue<T>),
}>
| AtomFamilyOptionsWithoutDefault<T, P>;

Expand Down Expand Up @@ -118,7 +123,7 @@ function atomFamily<T, P: Parameter>(
| Loadable<T>
| WrappedValue<T>
| T
| (P => T | RecoilValue<T> | Promise<T>) =
| (P => T | RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T>) =
'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
Expand Down
32 changes: 32 additions & 0 deletions packages/recoil/recoil_values/__tests__/Recoil_atomFamily-test.js
Expand Up @@ -39,6 +39,7 @@ let store: Store,
atom,
atomFamily,
selectorFamily,
RecoilLoadable,
pAtom;

const testRecoil = getRecoilTestFn(() => {
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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', () => {
Expand Down
4 changes: 2 additions & 2 deletions typescript/index.d.ts
Expand Up @@ -411,7 +411,7 @@ interface AtomFamilyOptionsWithoutDefault<T, P extends SerializableParam> {
| Loadable<T>
| WrappedValue<T>
| T
| ((param: P) => T | RecoilValue<T> | Promise<T>);
| ((param: P) => T | RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T>);
}
export type AtomFamilyOptions<T, P extends SerializableParam> =
| AtomFamilyOptionsWithDefault<T, P>
Expand Down Expand Up @@ -440,7 +440,7 @@ interface AtomFamilyOptionsWithoutDefault<T, P extends SerializableParam> {
get: (param: P) => (opts: {
get: GetRecoilValue,
getCallback: GetCallback,
}) => Promise<T> | RecoilValue<T> | T;
}) => Promise<T> | Loadable<T> | WrappedValue<T> | RecoilValue<T> | T;
set: (
param: P,
) => (
Expand Down
7 changes: 7 additions & 0 deletions typescript/tests.ts
Expand Up @@ -426,6 +426,13 @@ isRecoilValue(mySelector1);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const myAtomFamilyWithoutDefault: (number: number) => RecoilState<number> =
atomFamily<number, number>({key: 'MyAtomFamilyWithoutDefault'});

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const myAsyncAtomFamily: (number: number) => RecoilState<number> =
atomFamily<number, number>({
key: 'MyAsyncAtomFamily',
default: (param: number) => Promise.resolve(param),
});
}

/**
Expand Down

0 comments on commit d922baa

Please sign in to comment.