Skip to main content

Trees, Paths, and Data Structures

Keys and Object Helpers

ExportSignatureDescription
hashKey(key: unknown) => stringSerializes any value to a stable JSON string, sorting object keys (and symbol keys after them, prefixed @@) so structurally-equal inputs hash identically regardless of key order. Used as the framework's queryKeyHashFn.
mergeWith<T extends object>(target: T, source: Partial<T>, overrideExisting?: boolean) => TShallow, top-level merge of source into target, in place (the mutated target is also returned). undefined source values are always skipped; a defined target value is only overwritten when overrideExisting is true (default false — i.e. fill in missing values only).

Path Helpers

Built on path-browserify (POSIX-style, browser-safe).

ExportSignatureDescription
PathObject{ root: string; dir: string; base: string; ext: string; name: string }The parsed-path shape used by parsePath / formatPath.
getBaseName(filePath: string, keepExt?: boolean) => stringFinal path segment; strips the extension when keepExt is false (default true).
getExtName(filePath: string) => stringFile extension, including the leading dot.
getDirName(filePath: string) => stringDirectory portion of a path.
joinPaths(...paths: string[]) => stringJoins path segments and normalizes the result.
isAbsolutePath(filePath: string) => booleanWhether a path is absolute.
normalizePath(filePath: string) => stringResolves . / .. segments.
parsePath(filePath: string) => PathObjectParses a path string into its components.
formatPath(pathObject: PathObject) => stringInverse of parsePath.
getRelativePath(from: string, to: string) => stringRelative path from from to to.
resolvePath(...pathSegments: string[]) => stringResolves a sequence of segments into an absolute path.
pathSeparatorstringThe path segment separator ("/").

Pinyin Helpers

Built on pinyin-pro, with the modern Chinese word data (@pinyin-pro/data/modern) loaded lazily on first use for accurate polyphone resolution.

ExportSignatureDescription
WithPinyin<T, K>type WithPinyin<T extends AnyObject, K extends keyof T & string>Adds ${K}Pinyin / ${K}PinyinInitials fields for each key K — required when T[K] is a required string, optional when T[K] is optional, and omitted entirely for non-string keys.
getPinyin(text: string) => string[]Full toneless pinyin syllables for each character in text (non-Chinese runs kept as consecutive text, surnames read as surnames), memoized per input string.
getPinyinInitials(text: string) => string[]First-letter initials for each character in text, memoized per input string.
withPinyin<T extends AnyObject, K extends keyof T & string>(obj: T, ...keys: K[]) => WithPinyin<T, K>Returns a shallow copy of obj with {key}Pinyin / {key}PinyinInitials fields added for each given key whose value is a string, e.g. withPinyin({ name: "张三" }, "name") → adds namePinyin / namePinyinInitials.

Table Update Helpers

ExportSignatureDescription
CompareMode"reference" | "shallow" | "deep"Comparison strategy for shouldUpdateByKeys.
ShouldUpdateByKeysOptions{ compare?: CompareMode }Options for shouldUpdateByKeys (default compare: "reference").
shouldUpdateByKeys(options: ShouldUpdateByKeysOptions, ...keys: K[]) => (next: T, prev: T) => boolean (or the options-less overload (...keys: K[]) => (next: T, prev: T) => boolean)Builds a shouldCellUpdate-style comparator that returns true when any of the given keys differ between next and prev, using the chosen comparison mode. Intended for Table's shouldCellUpdate prop.

Tree Helpers

All tree functions default childrenKey to "children" and operate non-destructively (they return new arrays/nodes rather than mutating input, except buildTree/flattenTree, which read but do not mutate the source array).

ExportSignatureDescription
FlattenTreeOptions<TNode, TTransformedNode>{ childrenKey?; includeParent?; includeLevel?; transform?; filter? }Options for flattenTree. filter skips a node but still traverses its children; transform overrides the default flattened shape.
FlattenedNode<TNode>{ data: TNode; parent?: TNode; level?: number }The default per-node shape flattenTree produces when no transform is given.
flattenTree<TNode, TTransformedNode>(tree: TNode[], options?: FlattenTreeOptions<TNode, TTransformedNode>) => TTransformedNode[]Flattens a tree into a one-dimensional array, depth-first.
KeyAccessor<T>keyof T | ((node: T) => unknown)A property name or getter function used to read a node's id/parent-id in buildTree.
BuildTreeOptions<TNode, TTransformedNode, TChildrenKey>{ idKey?; parentIdKey?; childrenKey?; rootValue?; transform? }Options for buildTree (defaults: idKey: "id", parentIdKey: "parentId"). rootValue is either the parent-id value that marks a root, or a predicate.
BuildTreeResultNode<TNode, TChildrenKey>TNode & { [K in TChildrenKey]?: BuildTreeResultNode<TNode, TChildrenKey>[] }The tree-shaped node type buildTree returns.
buildTree<TNode, TTransformedNode, TChildrenKey extends string = "children">(nodes: TNode[], options?: BuildTreeOptions<TNode, TTransformedNode, TChildrenKey>) => BuildTreeResultNode<TTransformedNode, TChildrenKey>[]Builds a tree from a flat array via id/parent-id references; nodes whose parent is missing are treated as roots.
findNodeInTree<TNode>(tree: TNode[], predicate: (node: TNode, context: { parent?: TNode; level: number }) => boolean, childrenKey?: keyof TNode) => TNode | undefinedDepth-first search for the first matching node.
TraverseTreeOptions<TNode>{ strategy?: "dfs" | "bfs"; childrenKey?: keyof TNode }Options for traverseTree (default strategy: "dfs").
traverseTree<TNode>(tree: TNode[], callback: (node: TNode, context: { parent?: TNode; level: number; index: number }) => void, options?: TraverseTreeOptions<TNode>) => voidVisits every node depth-first or breadth-first, calling callback for side effects.
mapTree<TNode, TMappedNode>(tree: TNode[], callback: (node: TNode, context: { parent?: TNode; level: number; index: number }) => TMappedNode, childrenKey?: keyof TNode) => TMappedNode[]Maps every node to a new shape, preserving tree structure.
filterTree<TNode>(tree: TNode[], predicate: (node: TNode, context: { parent?: TNode; level: number; index: number }) => boolean, childrenKey?: keyof TNode) => TNode[]Removes non-matching nodes; a matching node keeps only its matching descendants.
filterTreeWithAncestors<TNode>(tree: TNode[], predicate: (node: TNode, context: { parent?: TNode; level: number; index: number }) => boolean, childrenKey?: keyof TNode) => TNode[]Like filterTree, but keeps every ancestor of a matching node even when the ancestor itself doesn't match — useful for search/filter UIs that must show the full path to a hit.

These exports are especially useful in department trees, menu trees, and tree-table pages.