@nimir/dot-path
v3.0.1
Published
Dot path resolver for typescript
Downloads
26
Maintainers
Readme
@nimir/dot-path - Typescript friendly object/tuple path resolve
Full thanks to gmarkov and his dot-path-value.
This library allows for performant extraction and setting of nested elements via a typesafe dot-path.
Install
pnpm install @nimir/dot-pathnpm install @nimir/dot-pathyarn add @nimir/dot-pathdeno install npm:@nimir/dot-pathbun install npm:@nimir/dot-pathFeatures
Path<T>- Get all paths of T in dotted string format.PathAt<T, Y>- Get the type of value at path Y of T.PathOf<T, Y>- Get all paths with type Y of T in dotted string format.get(item, path)- Get value by path with type-safety.set(item, path, value)- Set value by path with type-safety.- Supports object, array, tuple and recursive types.
Usage
Usage of Path utilities
import type { Path } from '@nimir/dot-path';
type Item = {
a: { b: { c: string } };
b: number;
c: string;
};
Path<Item>;
// ^? "a.b.c" | "b" | "a.b" | "a"
PathOf<Item, string>;
// ^? "a.b.c" | "c"
PathOf<Item, number | string>;
// ^? "a.b.c" | "b" | "c"
PathOf<Item, { c: number }>;
// ^? "a.b"
PathAt<Item, 'a.b.c'>;
// ^? string
PathAt<Item, 'a.b'>;
// ^? { c: string }
PathAt<Item, 'a.b.c.d'>;
// ^? never
PathAt<Item, 'a.b.c' | 'a.b'>;
// ^? string | { c: string }
type RecursiveItem = {
a: RecursiveItem;
b: number;
};
Path<RecursiveItem>;
// ^? "a" | "b" // Does Not throw typescript lsp into an infinite loopUsage with an object
import { get, set } from '@nimir/dot-path';
type Item = {
a: { b: { c: string } };
b: number;
c: string;
};
const item: Item = {
a: { b: { c: 'hello' } },
b: 0xbeef,
c: 'world!',
};
get(item, 'a.b.c');
// -> string
get(item, 'a.b');
// -> number
get(item, 'himom!');
// -> undefined
set(item, 'a.b.c', 'himom!');
// valid
set(item, 'a.b.c', 0xbeef);
// invalid
set(item, 'a.b', { c: 'himom!' });
// validUsage with a tuple
import { get, set } from '@nimir/dot-path';
type Item = {
a: { b: { c: string } };
b: number;
};
type Tuple = [string, [first: Item, second: Item]];
const tuple: Tuple = ['hello', [item, item]];
get(tuple, '0');
// -> string
get(tuple, '1.0.a.b.c');
// -> string
get(tuple, '1');
// -> [first: Item, second: Item]
get(tuple, 'himom!');
// -> undefined
set(tuple, '0', 'himom!');
// valid
set(tuple, '1.0.a.b.c', 'himom!');
// valid
set(tuple, '1.0.a.b.c', 0xbeef);
// invalid
set(tuple, '1.0.a.b', { c: 'himom!' });
// validUsage with an array
import { get, set } from '@nimir/dot-path';
type Item = {
a: { b: { c: string } };
b: number;
c: string;
};
const items: Item[] = [item, item];
get(items, '0');
// -> Item
get(items, '1.a.b.c');
// -> string
get(items, 'himom!');
// -> undefined
set(items, '0', { a: { b: { c: 'himom!' } }, b: 0xbeef });
// valid
set(items, '1.a.b.c', 'himom!');
// valid
set(items, '1.a.b.c', 0xbeef);
// invalid
set(items, '1.a.b', { c: 'himom!' });
// validCaveats
- Ergonomics first - The library does not guard against users' type mistakes, performs no runtime checks, and swallows all access errors returning an undefined instead. Its meant for its utility value.
- Tuple Size Limitation - Tuple path resolution is limited to 16 elements (indices 0-16). Tuples larger than this will not have proper type inference for indices beyond 16.
- Mutation Behavior - The
setfunction mutates the input object and returns the same reference. It does not create a deep copy. - Object Creation - When creating intermediate paths,
setalways creates plain objects{}. This can cause type mismatches if the expected structure contains arrays. - No Prototype Pollution Protection - The library does not guard against prototype pollution attacks. Avoid using untrusted input as paths.
