UNPKG

18.2 kBTypeScriptView Raw
1// Minimum TypeScript Version: 3.7
2
3/**
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 *
9 * @emails oncall+recoil
10 */
11
12/**
13 * This file is a manual translation of the flow types, which are the source of truth, so we should not introduce new terminology or behavior in this file.
14 */
15
16 export { };
17
18 import * as React from 'react';
19
20 // state.d.ts
21 type NodeKey = string;
22
23 // node.d.ts
24 export class DefaultValue {
25 private __tag: 'DefaultValue';
26 }
27
28 // recoilRoot.d.ts
29 export type RecoilRootProps = {
30 initializeState?: (mutableSnapshot: MutableSnapshot) => void,
31 override?: true,
32 } | {override: false};
33
34 /**
35 * Root component for managing Recoil state. Most Recoil hooks should be
36 * called from a component nested in a <RecoilRoot>
37 */
38 export const RecoilRoot: React.FC<RecoilRootProps>;
39
40 // Snapshot.d.ts
41 declare const SnapshotID_OPAQUE: unique symbol;
42 export interface SnapshotID {
43 readonly [SnapshotID_OPAQUE]: true;
44 }
45
46 interface ComponentInfo {
47 name: string;
48 }
49
50 interface RecoilStateInfo<T> {
51 loadable?: Loadable<T>;
52 isActive: boolean;
53 isSet: boolean;
54 isModified: boolean; // TODO report modified selectors
55 type: 'atom' | 'selector' | undefined; // undefined until initialized for now
56 deps: Iterable<RecoilValue<T>>;
57 subscribers: {
58 nodes: Iterable<RecoilValue<T>>,
59 components: Iterable<ComponentInfo>,
60 };
61 }
62
63 export class Snapshot {
64 getID(): SnapshotID;
65 getLoadable<T>(recoilValue: RecoilValue<T>): Loadable<T>;
66 getPromise<T>(recoilValue: RecoilValue<T>): Promise<T>;
67 getNodes_UNSTABLE(opts?: { isModified?: boolean, isInitialized?: boolean }): Iterable<RecoilValue<unknown>>;
68 getInfo_UNSTABLE<T>(recoilValue: RecoilValue<T>): RecoilStateInfo<T>;
69 map(cb: (mutableSnapshot: MutableSnapshot) => void): Snapshot;
70 asyncMap(cb: (mutableSnapshot: MutableSnapshot) => Promise<void>): Promise<Snapshot>;
71 retain(): () => void;
72 }
73
74 export class MutableSnapshot extends Snapshot {
75 set: SetRecoilState;
76 reset: ResetRecoilState;
77 }
78
79 // Effect is called the first time a node is used with a <RecoilRoot>
80 export type AtomEffect<T> = (param: {
81 node: RecoilState<T>,
82 trigger: 'set' | 'get',
83
84 // Call synchronously to initialize value or async to change it later
85 setSelf: (param:
86 | T
87 | DefaultValue
88 | Promise<T | DefaultValue>
89 | ((param: T | DefaultValue) => T | DefaultValue),
90 ) => void,
91 resetSelf: () => void,
92
93 // Subscribe callbacks to events.
94 // Atom effect observers are called before global transaction observers
95 onSet: (
96 param: (newValue: T, oldValue: T | DefaultValue, isReset: boolean) => void,
97 ) => void,
98
99 // Accessors to read other atoms/selectors
100 getPromise: <S>(recoilValue: RecoilValue<S>) => Promise<S>,
101 getLoadable: <S>(recoilValue: RecoilValue<S>) => Loadable<S>,
102 getInfo_UNSTABLE: <S>(recoilValue: RecoilValue<S>) => RecoilStateInfo<S>,
103 }) => void | (() => void);
104
105 // atom.d.ts
106 export interface AtomOptions<T> {
107 key: NodeKey;
108 default: RecoilValue<T> | Promise<T> | T;
109 effects_UNSTABLE?: ReadonlyArray<AtomEffect<T>>;
110 dangerouslyAllowMutability?: boolean;
111 }
112
113 /**
114 * Creates an atom, which represents a piece of writeable state
115 */
116export function atom<T>(options: AtomOptions<T>): RecoilState<T>;
117
118 // selector.d.ts
119 export type GetRecoilValue = <T>(recoilVal: RecoilValue<T>) => T;
120 export type GetCallback = <Args extends ReadonlyArray<unknown>, Return>(
121 fn: (interface: Readonly<{snapshot: Snapshot}>) => (...args: Args) => Return,
122 ) => (...args: Args) => Return;
123
124 export type SetRecoilState = <T>(
125 recoilVal: RecoilState<T>,
126 newVal: T | DefaultValue | ((prevValue: T) => T | DefaultValue),
127 ) => void;
128
129 export type ResetRecoilState = (recoilVal: RecoilState<any>) => void; // eslint-disable-line @typescript-eslint/no-explicit-any
130
131 // export type EqualityPolicy = 'reference' | 'value'; TODO: removing while we discuss long term API
132
133 export type EvictionPolicy = 'lru' | 'keep-all' | 'most-recent';
134
135 // TODO: removing while we discuss long term API
136 // export type CachePolicy =
137 // | {eviction: 'lru', maxSize: number, equality?: EqualityPolicy}
138 // | {eviction: 'none', equality?: EqualityPolicy}
139 // | {eviction?: undefined, equality: EqualityPolicy};
140
141 // TODO: removing while we discuss long term API
142 // export interface CachePolicyWithoutEviction {
143 // equality: EqualityPolicy;
144 // }
145
146 export type CachePolicyWithoutEquality = {eviction: 'lru', maxSize: number} | {eviction: 'keep-all'} | {eviction: 'most-recent'};
147
148 export interface ReadOnlySelectorOptions<T> {
149 key: string;
150 get: (opts: {
151 get: GetRecoilValue,
152 getCallback: GetCallback,
153 }) => Promise<T> | RecoilValue<T> | T;
154 dangerouslyAllowMutability?: boolean;
155 cachePolicy_UNSTABLE?: CachePolicyWithoutEquality; // TODO: using the more restrictive CachePolicyWithoutEquality while we discuss long term API
156 }
157
158 export interface ReadWriteSelectorOptions<T> extends ReadOnlySelectorOptions<T> {
159 set: (
160 opts: {
161 set: SetRecoilState;
162 get: GetRecoilValue;
163 reset: ResetRecoilState;
164 },
165 newValue: T | DefaultValue,
166 ) => void;
167 }
168
169 /**
170 * Creates a selector which represents derived state.
171 */
172 export function selector<T>(options: ReadWriteSelectorOptions<T>): RecoilState<T>;
173 export function selector<T>(options: ReadOnlySelectorOptions<T>): RecoilValueReadOnly<T>;
174
175 // hooks.d.ts
176 export type SetterOrUpdater<T> = (valOrUpdater: ((currVal: T) => T) | T) => void;
177 export type Resetter = () => void;
178 export interface TransactionInterface_UNSTABLE {
179 get<T>(a: RecoilValue<T>): T;
180 set<T>(s: RecoilState<T>, u: ((currVal: T) => T) | T): void;
181 reset(s: RecoilState<any>): void;
182 }
183 export type CallbackInterface = Readonly<{
184 set: <T>(recoilVal: RecoilState<T>, valOrUpdater: ((currVal: T) => T) | T) => void;
185 reset: (recoilVal: RecoilState<any>) => void; // eslint-disable-line @typescript-eslint/no-explicit-any
186 snapshot: Snapshot,
187 gotoSnapshot: (snapshot: Snapshot) => void,
188 transact_UNSTABLE: (cb: (i: TransactionInterface_UNSTABLE) => void) => void;
189 }>;
190
191 /**
192 * Returns the value of an atom or selector (readonly or writeable) and
193 * subscribes the components to future updates of that state.
194 */
195 export function useRecoilValue<T>(recoilValue: RecoilValue<T>): T;
196
197 /**
198 * Returns a Loadable representing the status of the given Recoil state
199 * and subscribes the component to future updates of that state. Useful
200 * for working with async selectors.
201 */
202 export function useRecoilValueLoadable<T>(recoilValue: RecoilValue<T>): Loadable<T>;
203
204 /**
205 * Returns a tuple where the first element is the value of the recoil state
206 * and the second is a setter to update that state. Subscribes component
207 * to updates of the given state.
208 */
209 export function useRecoilState<T>(recoilState: RecoilState<T>): [T, SetterOrUpdater<T>];
210
211 /**
212 * Returns a tuple where the first element is a Loadable and the second
213 * element is a setter function to update the given state. Subscribes
214 * component to updates of the given state.
215 */
216 export function useRecoilStateLoadable<T>(recoilState: RecoilState<T>): [Loadable<T>, SetterOrUpdater<T>];
217
218 /**
219 * Returns a setter function for updating Recoil state. Does not subscribe
220 * the component to the given state.
221 */
222
223 export function useSetRecoilState<T>(recoilState: RecoilState<T>): SetterOrUpdater<T>;
224
225 /**
226 * Returns a function that will reset the given state to its default value.
227 */
228 export function useResetRecoilState(recoilState: RecoilState<any>): Resetter; // eslint-disable-line @typescript-eslint/no-explicit-any
229
230 /**
231 * Returns current info about an atom
232 */
233 export function useGetRecoilValueInfo_UNSTABLE(): <T>(recoilValue: RecoilValue<T>) => RecoilStateInfo<T>;
234
235 /**
236 * Returns a function that will run the callback that was passed when
237 * calling this hook. Useful for accessing Recoil state in response to
238 * events.
239 */
240 export function useRecoilCallback<Args extends ReadonlyArray<unknown>, Return>(
241 fn: (interface: CallbackInterface) => (...args: Args) => Return,
242 deps?: ReadonlyArray<unknown>,
243 ): (...args: Args) => Return;
244
245 /**
246 * Returns a function that executes an atomic transaction for updating Recoil state.
247 */
248 export function useRecoilTransaction_UNSTABLE<Args extends ReadonlyArray<unknown>>(
249 fn: (interface: TransactionInterface_UNSTABLE) => (...args: Args) => void,
250 deps?: ReadonlyArray<unknown>,
251 ): (...args: Args) => void;
252
253 export function useRecoilTransactionObserver_UNSTABLE(
254 callback: (opts: {
255 snapshot: Snapshot,
256 previousSnapshot: Snapshot,
257 }) => void,
258 ): void;
259
260 /**
261 * Updates Recoil state to match the provided snapshot.
262 */
263 export function useGotoRecoilSnapshot(): (snapshot: Snapshot) => void;
264
265 /**
266 * Returns a snapshot of the current Recoil state and subscribes the component
267 * to re-render when any state is updated.
268 */
269 export function useRecoilSnapshot(): Snapshot;
270
271 // useRecoilRefresher.d.ts
272 /**
273 * Clears the cache for a selector causing it to be reevaluated.
274 */
275 export function useRecoilRefresher_UNSTABLE(recoilValue: RecoilValue<any>): () => void;
276
277 // useRecoilBridgeAcrossReactRoots.d.ts
278 export const RecoilBridge: React.FC;
279 /**
280 * Returns a component that acts like a <RecoilRoot> but shares the same store
281 * as the current <RecoilRoot>.
282 */
283 export function useRecoilBridgeAcrossReactRoots_UNSTABLE(): typeof RecoilBridge;
284
285 // loadable.d.ts
286 interface BaseLoadable<T> {
287 getValue: () => T;
288 toPromise: () => Promise<T>;
289 valueOrThrow: () => T;
290 errorOrThrow: () => any;
291 promiseOrThrow: () => Promise<T>;
292 is: (other: Loadable<any>) => boolean;
293 map: <S>(map: (from: T) => Loadable<S> | Promise<S> | S) => Loadable<S>;
294 }
295
296 interface ValueLoadable<T> extends BaseLoadable<T> {
297 state: 'hasValue';
298 contents: T;
299 valueMaybe: () => T;
300 errorMaybe: () => undefined;
301 promiseMaybe: () => undefined;
302 }
303
304 interface LoadingLoadable<T> extends BaseLoadable<T> {
305 state: 'loading';
306 contents: Promise<T>;
307 valueMaybe: () => undefined;
308 errorMaybe: () => undefined;
309 promiseMaybe: () => Promise<T>;
310 }
311
312 interface ErrorLoadable<T> extends BaseLoadable<T> {
313 state: 'hasError';
314 contents: any;
315 valueMaybe: () => undefined;
316 errorMaybe: () => any;
317 promiseMaybe: () => undefined;
318 }
319
320 export type Loadable<T> =
321 | ValueLoadable<T>
322 | LoadingLoadable<T>
323 | ErrorLoadable<T>;
324
325 // recoilValue.d.ts
326 declare class AbstractRecoilValue<T> {
327 __tag: [T];
328 __cTag: (t: T) => void; // for contravariance
329
330 key: NodeKey;
331 constructor(newKey: NodeKey);
332 }
333
334 declare class AbstractRecoilValueReadonly<T> {
335 __tag: [T];
336
337 key: NodeKey;
338 constructor(newKey: NodeKey);
339 }
340
341 export class RecoilState<T> extends AbstractRecoilValue<T> {}
342 export class RecoilValueReadOnly<T> extends AbstractRecoilValueReadonly<T> {}
343 export type RecoilValue<T> = RecoilValueReadOnly<T> | RecoilState<T>;
344
345 /**
346 * Returns true if the parameter is a Recoil atom or selector.
347 */
348 export function isRecoilValue(val: unknown): val is RecoilValue<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
349
350 /** Utilities */
351
352 // bigint not supported yet
353 type Primitive = undefined | null | boolean | number | symbol | string;
354
355 export type SerializableParam =
356 | Primitive
357 | {toJSON: () => string}
358 | ReadonlyArray<SerializableParam>
359 | Readonly<{[key: string]: SerializableParam}>;
360
361 export interface AtomFamilyOptions<T, P extends SerializableParam> {
362 key: NodeKey;
363 dangerouslyAllowMutability?: boolean;
364 default: RecoilValue<T> | Promise<T> | T | ((param: P) => T | RecoilValue<T> | Promise<T>);
365 effects_UNSTABLE?: | ReadonlyArray<AtomEffect<T>> | ((param: P) => ReadonlyArray<AtomEffect<T>>);
366 // cachePolicyForParams_UNSTABLE?: CachePolicyWithoutEviction; TODO: removing while we discuss long term API
367 }
368
369 /**
370 * Returns a function which returns a memoized atom for each unique parameter value.
371 */
372 export function atomFamily<T, P extends SerializableParam>(
373 options: AtomFamilyOptions<T, P>,
374 ): (param: P) => RecoilState<T>;
375
376 export interface ReadOnlySelectorFamilyOptions<T, P extends SerializableParam> {
377 key: string;
378 get: (param: P) => (opts: {
379 get: GetRecoilValue,
380 getCallback: GetCallback,
381 }) => Promise<T> | RecoilValue<T> | T;
382 // cachePolicyForParams_UNSTABLE?: CachePolicyWithoutEviction; TODO: removing while we discuss long term API
383 cachePolicy_UNSTABLE?: CachePolicyWithoutEquality; // TODO: using the more restrictive CachePolicyWithoutEquality while we discuss long term API
384 dangerouslyAllowMutability?: boolean;
385 }
386
387 export interface ReadWriteSelectorFamilyOptions<T, P extends SerializableParam> {
388 key: string;
389 get: (param: P) => (opts: {
390 get: GetRecoilValue,
391 getCallback: GetCallback,
392 }) => Promise<T> | RecoilValue<T> | T;
393 set: (
394 param: P,
395 ) => (
396 opts: { set: SetRecoilState; get: GetRecoilValue; reset: ResetRecoilState },
397 newValue: T | DefaultValue,
398 ) => void;
399 // cachePolicyForParams_UNSTABLE?: CachePolicyWithoutEviction; TODO: removing while we discuss long term API
400 cachePolicy_UNSTABLE?: CachePolicyWithoutEquality; // TODO: using the more restrictive CachePolicyWithoutEquality while we discuss long term API
401 dangerouslyAllowMutability?: boolean;
402 }
403
404/**
405 * Returns a function which returns a memoized atom for each unique parameter value.
406 */
407export function selectorFamily<T, P extends SerializableParam>(
408options: ReadWriteSelectorFamilyOptions<T, P>,
409): (param: P) => RecoilState<T>;
410
411/**
412 * Returns a function which returns a memoized atom for each unique parameter value.
413 */
414export function selectorFamily<T, P extends SerializableParam>(
415options: ReadOnlySelectorFamilyOptions<T, P>,
416): (param: P) => RecoilValueReadOnly<T>;
417
418/**
419 * Returns a selector that always has a constant value.
420 */
421export function constSelector<T extends SerializableParam>(constant: T): RecoilValueReadOnly<T>;
422
423/**
424 * Returns a selector which is always in the provided error state.
425 */
426export function errorSelector(message: string): RecoilValueReadOnly<never>;
427
428/**
429 * Casts a selector to be a read-only selector
430 */
431export function readOnlySelector<T>(atom: RecoilValue<T>): RecoilValueReadOnly<T>;
432
433/**
434 * Returns a selector that has the value of the provided atom or selector as a Loadable.
435 * This means you can use noWait() to avoid entering an error or suspense state in
436 * order to manually handle those cases.
437 */
438export function noWait<T>(state: RecoilValue<T>): RecoilValueReadOnly<Loadable<T>>;
439
440 /* eslint-disable @typescript-eslint/no-explicit-any */
441
442 export type UnwrapRecoilValue<T> = T extends RecoilValue<infer R> ? R : never;
443
444 export type UnwrapRecoilValues<T extends Array<RecoilValue<any>> | { [key: string]: RecoilValue<any> }> = {
445 [P in keyof T]: UnwrapRecoilValue<T[P]>;
446 };
447 export type UnwrapRecoilValueLoadables<T extends Array<RecoilValue<any>> | { [key: string]: RecoilValue<any> }> = {
448 [P in keyof T]: Loadable<UnwrapRecoilValue<T[P]>>;
449 };
450
451 export function waitForNone<RecoilValues extends Array<RecoilValue<any>> | [RecoilValue<any>]>(
452 param: RecoilValues,
453 ): RecoilValueReadOnly<UnwrapRecoilValueLoadables<RecoilValues>>;
454
455 export function waitForNone<RecoilValues extends { [key: string]: RecoilValue<any> }>(
456 param: RecoilValues,
457 ): RecoilValueReadOnly<UnwrapRecoilValueLoadables<RecoilValues>>;
458
459 export function waitForAny<RecoilValues extends Array<RecoilValue<any>> | [RecoilValue<any>]>(
460 param: RecoilValues,
461 ): RecoilValueReadOnly<UnwrapRecoilValueLoadables<RecoilValues>>;
462
463 export function waitForAny<RecoilValues extends { [key: string]: RecoilValue<any> }>(
464 param: RecoilValues,
465 ): RecoilValueReadOnly<UnwrapRecoilValueLoadables<RecoilValues>>;
466
467 export function waitForAll<RecoilValues extends Array<RecoilValue<any>> | [RecoilValue<any>]>(
468 param: RecoilValues,
469 ): RecoilValueReadOnly<UnwrapRecoilValues<RecoilValues>>;
470
471 export function waitForAll<RecoilValues extends { [key: string]: RecoilValue<any> }>(
472 param: RecoilValues,
473 ): RecoilValueReadOnly<UnwrapRecoilValues<RecoilValues>>;
474
475 export function waitForAllSettled<RecoilValues extends Array<RecoilValue<any>> | [RecoilValue<any>]>(
476 param: RecoilValues,
477 ): RecoilValueReadOnly<UnwrapRecoilValueLoadables<RecoilValues>>;
478
479 export function waitForAllSettled<RecoilValues extends { [key: string]: RecoilValue<any> }>(
480 param: RecoilValues,
481 ): RecoilValueReadOnly<UnwrapRecoilValueLoadables<RecoilValues>>;
482
483 export type UnwrapLoadable<T> = T extends Loadable<infer R> ? R : never;
484 export type UnwrapLoadables<T extends Array<Loadable<any>> | { [key: string]: Loadable<any> }> = {
485 [P in keyof T]: UnwrapLoadable<T[P]>;
486 };
487
488 /* eslint-disable @typescript-eslint/no-unused-vars */
489 export namespace RecoilLoadable {
490 /**
491 * Factory to make a Loadable object. If a Promise is provided the Loadable will
492 * be in a 'loading' state until the Promise is either resolved or rejected.
493 */
494 function of<T>(x: T | Promise<T>): Loadable<T>;
495 /**
496 * Factory to make a Loadable object in an error state.
497 */
498 function error(x: any): ErrorLoadable<any>;
499 /**
500 * Factory to make a Loadable which is resolved when all of the Loadables provided
501 * to it are resolved or any one has an error. The value is an array of the values
502 * of all of the provided Loadables. This is comparable to Promise.all() for Loadables.
503 */
504 function all<Inputs extends Array<Loadable<any>> | [Loadable<any>]>(inputs: Inputs): Loadable<UnwrapLoadables<Inputs>>;
505 function all<Inputs extends {[key: string]: Loadable<any>}>(inputs: Inputs): Loadable<UnwrapLoadables<Inputs>>;
506 /**
507 * Returns true if the provided parameter is a Loadable type.
508 */
509 function isLoadable(x: any): x is Loadable<any>;
510 }
511 /* eslint-enable @typescript-eslint/no-unused-vars */
512
513 /* eslint-enable @typescript-eslint/no-explicit-any */
514
515 /**
516 * Factory to produce a Recoil snapshot object with all atoms in the default state.
517 */
518 export function snapshot_UNSTABLE(initializeState?: (shapshot: MutableSnapshot) => void): Snapshot;