shelving
Version:
Toolkit for using data in JavaScript.
68 lines (67 loc) • 4.4 kB
TypeScript
import type { ImmutableArray } from "./array.js";
import type { EntryObject } from "./entry.js";
import type { AnyCaller } from "./function.js";
import type { DeepPartial } from "./object.js";
/** Data object. */
export type Data = {
readonly [K in string]: unknown;
};
/** Key for a data object prop. */
export type DataKey<T extends Data> = keyof T & string;
/** Value for a data object prop. */
export type DataValue<T extends Data> = T[keyof T & string];
/** Prop for a data object. */
export type DataProp<T extends Data> = {
readonly [K in DataKey<T>]: readonly [K, T[K]];
}[DataKey<T>];
/** Database is a set of named data objects. */
export type Database = {
readonly [K in string]: Data;
};
/**
* Flattened data object with every branch node of the data, flattened into `a.c.b` format.
* - Includes all branches, i.e. `{ a: { a2: number } }` will be `{ "a": object, "a.a2": number }`
*/
export type BranchData<T extends Data> = EntryObject<BranchProp<T>>;
/** Key for a flattened data object with deep keys flattened into `a.c.b` format. */
export type BranchKey<T extends Data> = BranchProp<T>[0];
/** Value for a flattened data object with deep keys flattened into `a.c.b` format. */
export type BranchValue<T extends Data> = BranchProp<T>[1];
/** Prop for a flattened data object with deep keys flattened into `a.c.b` format. */
export type BranchProp<T extends Data> = {
readonly [K in DataKey<T>]: (T[K] extends Data ? readonly [null, T[K]] | BranchProp<T[K]> : readonly [null, T[K]]) extends infer E ? E extends readonly [infer KK, infer VV] ? readonly [KK extends string ? `${K}.${KK}` : K, VV] : never : never;
}[DataKey<T>];
/**
* Flattened data object with only leaf nodes of the data, flattened into `a.c.b` format.
* - Only include leaf nodes, i.e. `{ a: { a2: number } }` will be `{ "a.a2": number }`
*/
export type LeafData<T extends Data> = EntryObject<LeafProp<T>>;
/** Key for a flattened data object with deep keys flattened into `a.c.b` format. */
export type LeafKey<T extends Data> = LeafProp<T>[0];
/** Value for a flattened data object with deep keys flattened into `a.c.b` format. */
export type LeafValue<T extends Data> = LeafProp<T>[1];
/** Prop for a flattened data object with deep keys flattened into `a.c.b` format. */
export type LeafProp<T extends Data> = {
readonly [K in DataKey<T>]: (T[K] extends Data ? LeafProp<T[K]> : readonly [null, T[K]]) extends infer E ? E extends readonly [infer KK, infer VV] ? readonly [KK extends string ? `${K}.${KK}` : K, VV] : never : never;
}[DataKey<T>];
/** Is an unknown value a data object? */
export declare function isData(value: unknown): value is Data;
/** Assert that an unknown value is a data object. */
export declare function assertData(value: unknown, caller?: AnyCaller): asserts value is Data;
/** Convert a data object or set of `DataProp` props for that object back into the full object. */
export declare function getData<T extends Data>(input: T): T;
export declare function getData<T extends Data>(input: T | Iterable<DataProp<T>>): Partial<T>;
/** Is an unknown value the key for an own prop of a data object. */
export declare const isDataProp: <T extends Data>(data: T, key: unknown) => key is DataKey<T>;
/** Assert that an unknown value is the key for an own prop of a data object. */
export declare function assertDataProp<T extends Data>(data: T, key: unknown, caller?: AnyCaller): asserts key is DataKey<T>;
/** Get the props of a data object as a set of entries. */
export declare function getDataProps<T extends Data>(data: T): ImmutableArray<DataProp<T>>;
export declare function getDataProps<T extends Data>(data: T | Partial<T>): ImmutableArray<DataProp<T>>;
/** Get the props of a data object as a set of entries. */
export declare function getDataKeys<T extends Data>(data: T): ImmutableArray<DataKey<T>>;
export declare function getDataKeys<T extends Data>(data: T | Partial<T>): ImmutableArray<DataKey<T>>;
/** Get an optional (possibly deep) prop from a data object, or `undefined` if it doesn't exist. */
export declare function getDataProp<T extends Data, K extends BranchKey<T> = BranchKey<T>>(data: T, key: K): BranchData<T>[K];
export declare function getDataProp<T extends Data, K extends BranchKey<T> = BranchKey<T>>(data: DeepPartial<T>, key: K): BranchData<T>[K] | undefined;
export declare function getDataProp(data: Data, key: string): unknown;