react-native-onyx
Version:
State management for React Native
142 lines (141 loc) • 6.97 kB
TypeScript
import type { ForwardedRef } from 'react';
import type { IsEqual } from 'type-fest';
import type { CollectionKeyBase, ExtractOnyxCollectionValue, KeyValueMapping, OnyxCollection, OnyxEntry, OnyxKey, OnyxValue, Selector } from '../types';
/**
* Represents the base mapping options between an Onyx key and the component's prop.
*/
type BaseMapping<TComponentProps, TOnyxProps> = {
canEvict?: boolean | ((props: Omit<TComponentProps, keyof TOnyxProps>) => boolean);
initWithStoredValues?: boolean;
allowStaleData?: boolean;
};
/**
* Represents the base mapping options when an Onyx collection key is supplied.
*/
type CollectionBaseMapping<TOnyxKey extends CollectionKeyBase> = {
initialValue?: OnyxCollection<KeyValueMapping[TOnyxKey]>;
};
/**
* Represents the base mapping options when an Onyx non-collection key is supplied.
*/
type EntryBaseMapping<TOnyxKey extends OnyxKey> = {
initialValue?: OnyxEntry<KeyValueMapping[TOnyxKey]>;
};
/**
* Represents the string / function `key` mapping option between an Onyx key and the component's prop.
*
* If `key` is `string`, the type of the Onyx value that is associated with `key` must match with the type of the component's prop,
* otherwise an error will be thrown.
*
* If `key` is `function`, the return type of `key` function must be a valid Onyx key and the type of the Onyx value associated
* with `key` must match with the type of the component's prop, otherwise an error will be thrown.
*
* @example
* ```ts
* // Onyx prop with `string` key
* onyxProp: {
* key: ONYXKEYS.ACCOUNT,
* },
*
* // Onyx prop with `function` key
* onyxProp: {
* key: ({reportId}) => ONYXKEYS.ACCOUNT,
* },
* ```
*/
type BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey, TOnyxValue> = IsEqual<TOnyxValue, TOnyxProps[TOnyxProp]> extends true ? {
key: TOnyxKey | ((props: Omit<TComponentProps, keyof TOnyxProps> & Partial<TOnyxProps>) => TOnyxKey);
} : never;
/**
* Represents the string `key` and `selector` mapping options between an Onyx key and the component's prop.
*
* The function signature and return type of `selector` must match with the type of the component's prop,
* otherwise an error will be thrown.
*
* @example
* ```ts
* // Onyx prop with `string` key and selector
* onyxProp: {
* key: ONYXKEYS.ACCOUNT,
* selector: (value: Account | null): string => value?.id ?? '',
* },
* ```
*/
type BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, TReturnType, TOnyxKey extends OnyxKey> = {
key: TOnyxKey;
selector: Selector<TOnyxKey, TOnyxProps, TReturnType>;
};
/**
* Represents the function `key` and `selector` mapping options between an Onyx key and the component's prop.
*
* The function signature and return type of `selector` must match with the type of the component's prop,
* otherwise an error will be thrown.
*
* @example
* ```ts
* // Onyx prop with `function` key and selector
* onyxProp: {
* key: ({reportId}) => ONYXKEYS.ACCOUNT,
* selector: (value: Account | null) => value?.id ?? '',
* },
* ```
*/
type BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TReturnType, TOnyxKey extends OnyxKey> = {
key: (props: Omit<TComponentProps, keyof TOnyxProps> & Partial<TOnyxProps>) => TOnyxKey;
selector: Selector<TOnyxKey, TOnyxProps, TReturnType>;
};
/**
* Represents the mapping options between an Onyx key and the component's prop with all its possibilities.
*/
type Mapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey> = BaseMapping<TComponentProps, TOnyxProps> & EntryBaseMapping<TOnyxKey> & (BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxEntry<KeyValueMapping[TOnyxKey]>> | BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProps[TOnyxProp], TOnyxKey> | BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProps[TOnyxProp], TOnyxKey>);
/**
* Represents a superset of `Mapping` type with internal properties included.
*/
type WithOnyxMapping<TComponentProps, TOnyxProps> = Mapping<TComponentProps, TOnyxProps, keyof TOnyxProps, OnyxKey> & {
subscriptionID: number;
previousKey?: OnyxKey;
};
/**
* Represents the mapping options between an Onyx collection key without suffix and the component's prop with all its possibilities.
*/
type CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends CollectionKeyBase> = BaseMapping<TComponentProps, TOnyxProps> & CollectionBaseMapping<TOnyxKey> & (BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxCollection<KeyValueMapping[TOnyxKey]>> | BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, ExtractOnyxCollectionValue<TOnyxProps[TOnyxProp]>, TOnyxKey> | BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, ExtractOnyxCollectionValue<TOnyxProps[TOnyxProp]>, TOnyxKey>);
/**
* Represents an union type of all the possible Onyx key mappings.
* Each `OnyxPropMapping` will be associated with its respective Onyx key, ensuring different type-safety for each object.
*/
type OnyxPropMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps> = {
[TOnyxKey in OnyxKey]: Mapping<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>;
}[OnyxKey];
/**
* Represents an union type of all the possible Onyx collection keys without suffix mappings.
* Each `OnyxPropCollectionMapping` will be associated with its respective Onyx key, ensuring different type-safety for each object.
*/
type OnyxPropCollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps> = {
[TOnyxKey in CollectionKeyBase]: CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>;
}[CollectionKeyBase];
/**
* Represents an Onyx mapping object that connects Onyx keys to component's props.
*/
type MapOnyxToState<TComponentProps, TOnyxProps> = {
[TOnyxProp in keyof TOnyxProps]: OnyxPropMapping<TComponentProps, TOnyxProps, TOnyxProp> | OnyxPropCollectionMapping<TComponentProps, TOnyxProps, TOnyxProp>;
};
/**
* Represents the `withOnyx` internal component props.
*/
type WithOnyxProps<TComponentProps, TOnyxProps> = Omit<TComponentProps, keyof TOnyxProps> & {
forwardedRef?: ForwardedRef<unknown>;
};
/**
* Represents the `withOnyx` internal component state.
*/
type WithOnyxState<TOnyxProps> = TOnyxProps & {
loading: boolean;
};
/**
* Represents the `withOnyx` internal component instance.
*/
type WithOnyxInstance = React.Component<unknown, WithOnyxState<KeyValueMapping>> & {
setStateProxy: (modifier: Record<string, OnyxCollection<KeyValueMapping[OnyxKey]>> | ((state: Record<string, OnyxCollection<KeyValueMapping[OnyxKey]>>) => OnyxValue<OnyxKey>)) => void;
setWithOnyxState: (statePropertyName: OnyxKey, value: OnyxValue<OnyxKey>) => void;
};
export type { WithOnyxMapping, MapOnyxToState, WithOnyxProps, WithOnyxInstance, WithOnyxState };