UNPKG

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