get
The get utility safely retrieves a nested value from an object using a dot-notation path string. It prevents runtime errors when accessing properties of undefined or null intermediate objects and supports an optional default value.
Source Code
View Source Code
ts
import type { Obj } from '../types';
import { assert } from '../function/assert';
import { isNil } from '../typed/isNil';
import { IS_OBJECT_ERROR_MSG, isObject } from '../typed/isObject';
type PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}`
? Key extends keyof T
? PathValue<T[Key], Rest>
: undefined
: P extends keyof T
? T[P]
: undefined;
// #region PathOptions
type PathOptions = {
throwOnMissing?: boolean;
};
// #endregion PathOptions
/**
* Retrieves the value at a given path of the object. If the value is undefined, the default value is returned.
*
* @example
* ```ts
* const obj = { a: { b: { c: 3 } }, d: [1, 2, 3] };
*
* getValue(obj, 'a.b.c'); // 3
* getValue(obj, 'a.b.d', 'default'); // 'default'
* getValue(obj, 'd[1]'); // 2
* getValue(obj, 'e.f.g', 'default', { throwOnMissing: true }); // throws Error
* ```
*
* @template T - The type of the object to query.
* @template P - The type of the path string.
* @param item - The object to query.
* @param path - The dot-separated path of the property to get.
* @param [defaultValue] - The value returned for undefined resolved values.
* @param [options] - Additional options for value retrieval.
*
* @returns The resolved value.
*
* @throws If throwOnMissing is true and the path doesn't exist.
*/
export function get<T extends Obj, P extends string>(
item: T,
path: P,
defaultValue?: unknown,
options: PathOptions = {},
): PathValue<T, P> | undefined {
assert(isObject(item), IS_OBJECT_ERROR_MSG, { args: { item }, type: TypeError });
const { throwOnMissing = false } = options;
const fragments = path.split(/[.[\]]+/).filter(Boolean);
let current: any = item;
for (const fragment of fragments) {
if (isNil(current) || typeof current !== 'object') {
if (throwOnMissing) throw new Error(`Cannot read property '${fragment}' of ${current}`);
return defaultValue as PathValue<T, P>;
}
current = current[fragment];
if (current === undefined) {
if (throwOnMissing) throw new Error(`Property '${fragment}' does not exist`);
return defaultValue as PathValue<T, P>;
}
}
return current as PathValue<T, P>;
}Features
- Isomorphic: Works in both Browser and Node.js.
- Safe Access: Never throws if a parent is
nullorundefined(unlessthrowOnMissingis set). - Dot & Bracket Notation: Supports
'a.b.c'and'a[0].b'path formats. - Default Value: Provide a fallback value for missing or
undefinedpaths. - Type-safe: Generic return type with full TypeScript inference.
API
Type Definitions
ts
type PathOptions = {
throwOnMissing?: boolean;
};ts
function get<T extends object, P extends string>(
item: T,
path: P,
defaultValue?: unknown,
options?: PathOptions,
): unknown;Parameters
item: The object to query.path: The path to the desired property as a dot-separated (or bracket-notation) string.defaultValue: Optional. A value returned when the path is missing or resolves toundefined.options: Optional configuration:throwOnMissing: Iftrue, throws anErrorinstead of returning the default value.
Returns
The value at the path, the defaultValue, or undefined.
Examples
Basic Nested Access
ts
import { get } from '@vielzeug/toolkit';
const config = {
api: {
endpoints: {
login: '/api/v1/login',
},
},
};
get(config, 'api.endpoints.login'); // '/api/v1/login'
get(config, 'api.version'); // undefined
get(config, 'api.version', 'v1'); // 'v1' (default value)Array Index Access
ts
import { get } from '@vielzeug/toolkit';
const data = {
users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
],
};
get(data, 'users[0].name'); // 'Alice'
get(data, 'users[1].id'); // 2Throwing on Missing Paths
ts
import { get } from '@vielzeug/toolkit';
const obj = { a: { b: 1 } };
// Throws an error instead of returning the default value
get(obj, 'e.f.g', undefined, { throwOnMissing: true }); // throws ErrorImplementation Notes
- Bracket notation (
[0]) is parsed and treated as a key automatically. - Returns
defaultValueonly when the resolved value isundefined;nullis returned as-is.