Category: object Since: 1.0.0 Tags: object, nested, path, safe-access, typed, dot-notation
get
Safely gets a nested value from a plain object using a dot-separated path with full TypeScript type safety.
Usage
import { get } from "@petr-ptacek/js-core";
const user = {
profile: {
name: "John",
address: {
city: "Prague",
},
},
};
const name = get(user, "profile.name");
console.log(name); // "John"
const city = get(user, "profile.address.city");
console.log(city); // "Prague"
const age = get(user, "profile.age" as any, 0);
console.log(age); // 0Why This Utility Exists
Direct property access can throw runtime errors when intermediate properties are null or undefined. Optional chaining lacks type safety for deep paths and always returns potentially any types. This utility provides safe access with compile-time path validation and full type inference.
Signature
// Without default value
function get<T extends object, P extends DotPathKeys<T>>(obj: T, path: P): DotPathValue<T, P> | undefined;
// With default value
function get<T extends object, P extends DotPathKeys<T>, D>(
obj: T,
path: P,
defaultValue: D
): Exclude<DotPathValue<T, P>, undefined> | D;Parameters
obj(T extends object): The plain object to access.path(P extends DotPathKeys<T>): The dot-separated path string.defaultValue(D, optional): Value to return if the path resolves toundefined.
Type Parameters
<T extends object>: The type of the input object.<P extends DotPathKeys<T>>: The valid path type derived from the object structure.<D>: The type of the default value (when provided).
Return Type
Returns the value at the specified path, or undefined if the path doesn't exist. When a default value is provided, returns the default value instead of undefined for missing paths. The return type is automatically inferred based on the path and object structure.
Design Notes
The utility uses DotPathKeys<T> and DotPathValue<T, P> from the type category to validate paths at compile time. Only valid paths that exist in the plain object structure are accepted.
Only plain objects are traversed. Arrays, Date, Map, Set, functions, and other non-plain-object values are treated as leaves — traversal stops and undefined is returned when a path segment reaches such a value.
When To Use
Use get when you need:
- safe deep property access without runtime errors
- type-safe path strings validated at compile time
- fallback values for missing properties
When Not To Use
Avoid when:
- shallow access where optional chaining (
obj?.prop) is sufficient - the path goes through an array or non-plain-object value — those are not traversed
- dynamic paths that cannot be known at compile time
- performance-critical code where direct access is faster
Summary
get provides safe and type-safe access to nested plain object properties with compile-time path validation and graceful handling of missing values.
Snippets
api-response.ts
import { get } from "@petr-ptacek/js-core";
const apiResponse = {
data: {
user: {
id: 1,
profile: {
email: "alice@example.com",
preferences: { theme: "dark" },
},
},
meta: {
pagination: {
total: 42,
page: 1,
},
},
},
};
// Safely access nested API data
const userEmail = get(apiResponse, "data.user.profile.email");
console.log(userEmail); // "alice@example.com"
const userTheme = get(apiResponse, "data.user.profile.preferences.theme", "light");
console.log(userTheme); // "dark"
// Access meta information with defaults
const total = get(apiResponse, "data.meta.pagination.total", 0);
console.log(total); // 42basic.ts
import { get } from "@petr-ptacek/js-core";
const user = {
profile: {
name: "John",
age: 30,
address: {
city: "Prague",
zip: "110 00",
},
},
};
// Get nested object property
const name = get(user, "profile.name");
console.log(name); // "John"
// Get deeply nested value
const city = get(user, "profile.address.city");
console.log(city); // "Prague"
// Get with default value (existing property)
const age = get(user, "profile.age", 25);
console.log(age); // 30
// Get with default value (missing property)
const nickname = get(user, "profile.nickname" as any, "anonymous");
console.log(nickname); // "anonymous"config.ts
import { get } from "@petr-ptacek/js-core";
const config = {
server: {
port: 3000,
host: "localhost",
ssl: true,
database: {
host: "db.example.com",
credentials: {
username: "admin",
password: "secret123",
},
},
},
};
// Access configuration values with sensible defaults
const port = get(config, "server.port", 8080);
const host = get(config, "server.host", "0.0.0.0");
const sslEnabled = get(config, "server.ssl", false);
// Access deeply nested configuration
const dbHost = get(config, "server.database.host", "localhost");
const dbUser = get(config, "server.database.credentials.username", "user");
console.log({
port,
host,
sslEnabled,
dbHost,
dbUser,
});