diff --git a/lib/Onyx.d.ts b/lib/Onyx.d.ts index 0c7fdd319..13803f27b 100644 --- a/lib/Onyx.d.ts +++ b/lib/Onyx.d.ts @@ -1,7 +1,6 @@ import {Component} from 'react'; -import {PartialDeep} from 'type-fest'; import * as Logger from './Logger'; -import {CollectionKey, CollectionKeyBase, DeepRecord, KeyValueMapping, OnyxCollection, OnyxEntry, OnyxKey, NullableProperties} from './types'; +import {CollectionKey, CollectionKeyBase, DeepRecord, KeyValueMapping, NullishDeep, OnyxCollection, OnyxEntry, OnyxKey} from './types'; /** * Represents a mapping object where each `OnyxKey` maps to either a value of its corresponding type in `KeyValueMapping` or `null`. @@ -79,14 +78,14 @@ type OnyxUpdate = | { onyxMethod: typeof METHOD.MERGE; key: TKey; - value: PartialDeep; + value: NullishDeep; }; }[OnyxKey] | { [TKey in CollectionKeyBase]: { onyxMethod: typeof METHOD.MERGE_COLLECTION; key: TKey; - value: Record<`${TKey}${string}`, PartialDeep>; + value: Record<`${TKey}${string}`, NullishDeep>; }; }[CollectionKeyBase]; @@ -202,7 +201,7 @@ declare function multiSet(data: Partial): Promise * @param key ONYXKEYS key * @param value Object or Array value to merge */ -declare function merge(key: TKey, value: NullableProperties>): Promise; +declare function merge(key: TKey, value: NullishDeep): Promise; /** * Clear out all the data in the store @@ -246,7 +245,7 @@ declare function clear(keysToPreserve?: OnyxKey[]): Promise; */ declare function mergeCollection( collectionKey: TKey, - collection: Collection>, + collection: Collection>, ): Promise; /** diff --git a/lib/types.d.ts b/lib/types.d.ts index c43d06403..b6eb8ba02 100644 --- a/lib/types.d.ts +++ b/lib/types.d.ts @@ -1,10 +1,13 @@ import {Merge} from 'type-fest'; +import {BuiltIns} from 'type-fest/source/internal'; /** * Represents a deeply nested record. It maps keys to values, * and those values can either be of type `TValue` or further nested `DeepRecord` instances. */ -type DeepRecord = {[key: string]: TValue | DeepRecord}; +type DeepRecord = { + [key: string]: TValue | DeepRecord; +}; /** * Represents type options to configure all Onyx methods. @@ -180,14 +183,42 @@ type OnyxEntry = TOnyxValue | null; */ type OnyxCollection = OnyxEntry>; +type NonTransformableTypes = + | BuiltIns + | ((...args: any[]) => unknown) + | Map + | Set + | ReadonlyMap + | ReadonlySet + | unknown[] + | readonly unknown[]; + /** - * The `NullableProperties` sets the values of all properties in `T` to be nullable (i.e., `| null`). - * It doesn't recurse into nested property values, this means it applies the nullability only to the top-level properties. + * Create a type from another type with all keys and nested keys set to optional or null. + * + * @example + * const settings: Settings = { + * textEditor: { + * fontSize: 14; + * fontColor: '#000000'; + * fontWeight: 400; + * } + * autosave: true; + * }; * - * @template T The type of the properties to convert to nullable properties. + * const applySavedSettings = (savedSettings: NullishDeep) => { + * return {...settings, ...savedSettings}; + * } + * + * settings = applySavedSettings({textEditor: {fontWeight: 500, fontColor: null}}); */ -type NullableProperties = { - [P in keyof T]: T[P] | null; +type NullishDeep = T extends NonTransformableTypes ? T : T extends object ? NullishObjectDeep : unknown; + +/** +Same as `NullishDeep`, but accepts only `object`s as inputs. Internal helper for `NullishDeep`. +*/ +type NullishObjectDeep = { + [KeyType in keyof ObjectType]?: NullishDeep | null; }; export { @@ -201,5 +232,5 @@ export { OnyxEntry, OnyxKey, Selector, - NullableProperties, + NullishDeep, };