isData()function
Is an unknown value a data object?
isData(value: unknown): value is Data
The Data type and its helpers are the foundation of Shelving's data layer. A Data object is a plain Record<string, unknown> — a JSON-safe object with no class prototype. Every database document, query result, and schema-validated value is a Data.
"user.address.city" or the equivalent tuple ["user", "address", "city"].getDataProp() never throws — it returns undefined for missing or non-object intermediate nodes.splitDataPath() / joinDataPath() are inverses of each other; both accept either form so you can freely convert.import { isData, assertData } from "shelving/util";
isData({ name: "Alice" }); // true
isData(new Map()); // false
isData(null); // false
assertData(value); // throws RequiredError if value is not a plain objectimport { isDataProp, assertDataProp, getDataProps, getDataKeys } from "shelving/util";
const doc = { name: "Alice", age: 30 };
isDataProp(doc, "name"); // true
isDataProp(doc, "email"); // false
getDataKeys(doc); // ["name", "age"]
getDataProps(doc); // [["name", "Alice"], ["age", 30]]import { getDataProp, splitDataPath, joinDataPath } from "shelving/util";
const doc = { user: { address: { city: "London" } } };
getDataProp(doc, "user.address.city"); // "London"
getDataProp(doc, ["user", "address", "city"]); // "London"
getDataProp(doc, "user.missing.key"); // undefined
splitDataPath("user.address.city"); // ["user", "address", "city"]
joinDataPath(["user", "address", "city"]); // "user.address.city"data.ts exports a rich set of mapped types for working with typed data objects:
| Type | Purpose |
|---|---|
Data | Base plain-object type |
PartialData<T> | All keys optional |
DataKey<T> | Union of string keys |
DataValue<T> | Union of value types |
LeafData<T> | Flat object with only leaf paths |
LeafDataPath<T> | Union of dotted leaf paths |
BranchData<T> | Flat object including intermediate object paths |
NestedData | One level of nesting: { Group: { key: value } } |
FlatData<T> | Flattened union of nested data |
import type { Data, LeafDataPath } from "shelving/util";
type Profile = { name: string; address: { city: string } };
type ProfileLeafPaths = LeafDataPath<Profile>; // "name" | "address.city"Is an unknown value a data object?
isData(value: unknown): value is Data
Assert that an unknown value is a data object.
assertData(value: unknown, caller: AnyCaller = assertData): asserts value is Data
Is an unknown value the key for an own prop of a data object?
isDataProp(data: T, key: unknown): key is DataKey<T>
Assert that an unknown value is the key for an own prop of a data object.
assertDataProp(data: T, key: unknown, caller: AnyCaller = assertDataProp): asserts key is DataKey<T>
Get the props of a data object as a set of entries.
getDataProps(data: T): ImmutableArray<DataProp<T>>
getDataProps(data: T | Partial<T>): ImmutableArray<DataProp<T>>
Get the keys of a data object as an array.
getDataKeys(data: T): ImmutableArray<DataKey<T>>
getDataKeys(data: T | Partial<T>): ImmutableArray<DataKey<T>>
Split a dotted path into data path segments.
splitDataPath(path: BranchDataPath<T> | BranchDataSegments<T>): BranchDataSegments<T>
splitDataPath(path: LeafDataPath<T> | LeafDataSegments<T>): LeafDataSegments<T>
splitDataPath(path: string | Segments): Segments
Join a set of data path segments into a dotted path string.
joinDataPath(path: BranchDataSegments<T> | BranchDataPath<T>): BranchDataPath<T>
joinDataPath(path: LeafDataSegments<T> | LeafDataPath<T>): LeafDataPath<T>
joinDataPath(path: Segments | string): string
Get an optional (possibly deep) prop from a data object, or undefined if it doesn't exist.
getDataProp(data: T, path: K): BranchData<T>[K]
getDataProp(data: DeepPartial<T>, path: K): BranchData<T>[K] | undefined
getDataProp(data: Data, path: string | Segments): unknown
Data object — a plain object with string keys and unknown values.
{ readonly [K in string]: unknown }Partial data object (values can be explicitly undefined).
{ readonly [K in keyof T]?: T[K] | undefined }Helper type to get the key for a data object prop.
keyof T & string
Helper type to get the value for a data object prop.
T[DataKey<T>]
Helper type to get a prop for a data object. i.e. DataProp<{ a: number }> produces readonly ["a", number"]
{
readonly [K in DataKey<T>]: readonly [K, T[K]];
}[DataKey<T>]Helper type to get a flattened data object with every branch node of the data, flattened into a.c.b format. i.e. BranchData<{ a: { a2: number } }> produces { "a": object, "a.a2": number }
EntryObject<BranchDataProp<T>>
Helper type to get the path for a flattened data object with deep paths flattened into a.c.b format.
BranchDataProp<T>[0]
Helper type to get the value for a flattened data object with deep paths flattened into a.c.b format.
BranchDataProp<T>[1]
Helper type to get the prop for a flattened data object with deep paths flattened into a.c.b format.
{
readonly [K in DataKey<T>]: (
T[K] extends Data
? readonly [null, T[K]] | BranchDataProp<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>]Typed path tuple for every branch node of a data object (including intermediate objects). i.e. BranchPath<{ a: number, b: { c: string } }> produces readonly ["a"] | readonly ["b"] | readonly ["b", "c"]
{
readonly [K in DataKey<T>]: T[K] extends Data ? readonly [K] | readonly [K, ...BranchDataSegments<T[K]>] : readonly [K];
}[DataKey<T>]Helper type to get a flattened data object with only leaf nodes of the data, flattened into a.c.b format. i.e. LeafData<{ a: { a2: number } }> produces { "a.a2": number }
EntryObject<LeafDataProp<T>>
Helper type to get the leaf paths for a flattened data object with deep paths flattened into a.c.b format.
LeafDataProp<T>[0]
Helper type to get the leaf values for a flattened data object with deep paths flattened into a.c.b format.
LeafDataProp<T>[1]
Helper type to get the leaf props for a flattened data object with deep paths flattened into a.c.b format.
{
readonly [K in DataKey<T>]: (
T[K] extends Data
? LeafDataProp<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>]Typed path tuple for only leaf nodes of a data object. i.e. LeafPath<{ a: number, b: { c: string } }> produces readonly ["a"] | readonly ["b", "c"]
{
readonly [K in DataKey<T>]: T[K] extends Data ? readonly [K, ...LeafDataSegments<T[K]>] : readonly [K];
}[DataKey<T>]Object with one level of data nested beneath each prop. i.e. { A: { a: number }, B: { b: string } }
{
readonly [key: string]: Data;
}Helper type to flatten one level of nested data into a single flat Data type. i.e. FlattenData<{ A: { a: number }, B: { b: string } }> produces { a: number, b: string }
Resolve<UnionToIntersection<T[keyof T]>>