@pico-brief/fallback_value
v1.0.1
Published
A safe, fully typed utility for reading deeply nested values from objects
Maintainers
Readme
fallbackValue
A safe, fully typed utility for reading deeply nested values from objects — without crashing when something along the way is missing.
fallbackValue knows the shape of your data at compile time, which means TypeScript will warn you if you mistype a path, and will automatically know what type the returned value is — no guessing required.
The problem it solves
Imagine you have data that looks like this:
const user = {
profile: {
address: {
city: "Springfield"
}
}
};To read city, you'd normally write:
const city = user.profile.address.city;But what if profile or address doesn't exist? JavaScript throws an error:
TypeError: Cannot read properties of undefined (reading 'city')You could guard against this manually:
const city = user.profile && user.profile.address && user.profile.address.city;But that gets messy fast. fallbackValue handles all of this for you in one clean call:
fallbackValue(user, "profile.address.city", "Unknown");
// → "Springfield" if it exists, "Unknown" if anything is missingAnd because it's fully typed, TypeScript knows the result is a string — so you get autocompletion and a compile-time error if you ever mistype the path:
fallbackValue(user, "profile.address.city", "Unknown"); // ✅ TypeScript knows this returns a string
fallbackValue(user, "profile.address.typo", "Unknown"); // ❌ TypeScript error — "typo" is not a valid pathInstallation
npm install @pico-brief/fallback_valueThen import it:
import fallbackValue from "@pico-brief/fallback_value";Basic usage
fallbackValue(object, path, defaultValue)| Parameter | What it is |
|----------------|---------------------------------------------------------|
| object | The object you want to read from |
| path | A string describing where to look (see Path Syntax) |
| defaultValue | What to return if the path leads nowhere (default: null) |
Path syntax
Paths are just strings that describe how to navigate into an object.
Dot notation — for regular object properties
fallbackValue(data, "user.name", "Anonymous")
// ─────┬────
// └─ reads data.user.nameBracket notation — for arrays
fallbackValue(data, "users[0].name", "Anonymous")
// ─┬─
// └─ reads the first item in the users arrayCombining both
fallbackValue(data, "company.employees[2].email", "N/A")
// reads: data → company → employees → item at index 2 → emailExamples
Simple object
const person = { name: "Alice", age: 30 };
fallbackValue(person, "name", "Unknown"); // → "Alice"
fallbackValue(person, "email", "No email"); // → "No email" (key doesn't exist)Nested object
const config = {
database: {
host: "localhost",
port: 5432
}
};
fallbackValue(config, "database.host", "127.0.0.1"); // → "localhost"
fallbackValue(config, "database.user", "root"); // → "root" (missing)Arrays
const data = {
scores: [10, 20, 30]
};
fallbackValue(data, "scores[0]", 0); // → 10
fallbackValue(data, "scores[9]", 0); // → 0 (index out of bounds)Arrays of objects
const store = {
users: [
{ name: "Alice", address: { city: "Springfield" } },
{ name: "Bob" }
]
};
fallbackValue(store, "users[0].address.city", "Unknown"); // → "Springfield"
fallbackValue(store, "users[1].address.city", "Unknown"); // → "Unknown" (Bob has no address)
fallbackValue(store, "users[5].name", "Unknown"); // → "Unknown" (index 5 doesn't exist)Without a path — simple null safety
You can also use fallbackValue without a path, just to safely handle null or undefined values:
let username = null;
fallbackValue(username, null, "Guest"); // → "Guest"With untyped data (e.g. from JSON.parse)
const raw: any = JSON.parse('{"settings": {"theme": "dark"}}');
fallbackValue(raw, "settings.theme", "light"); // → "dark"
fallbackValue(raw, "settings.font", "Arial"); // → "Arial" (missing)Edge cases handled
Key names that contain a dot
If your data has a key that literally contains a dot (e.g. "first.name"), escape it with a backslash:
const weird = { "first.name": "Alice" };
fallbackValue(weird, "first\\.name", "Unknown"); // → "Alice"
// ──┬──
// └─ backslash tells fallbackValue this dot is part of the key nameWithout the backslash, "first.name" would be read as two separate keys: first → name.
Stored undefined is treated as missing
const obj = { score: undefined };
fallbackValue(obj, "score", 0); // → 0Even though score exists as a key, its value is undefined, which fallbackValue treats the same as missing.
TypeScript support
If you're using TypeScript, fallbackValue will catch typos in your paths at compile time:
type User = { name: string; age: number };
const user: User = { name: "Alice", age: 30 };
fallbackValue(user, "name", "Unknown"); // ✅ works
fallbackValue(user, "typo", "Unknown"); // ❌ TypeScript error — "typo" is not a valid pathIt also knows what type the result will be, so you get proper autocompletion:
const name = fallbackValue(user, "name", "Unknown");
// ^^^^
// TypeScript knows this is a `string`Quick reference
// Read a nested value with a fallback
fallbackValue(obj, "a.b.c", "default")
// Read from an array
fallbackValue(obj, "items[0].name", "default")
// Mix of both
fallbackValue(obj, "users[2].address.city", "Unknown")
// Escaped dot in key name
fallbackValue(obj, "some\\.key.nested", "default")
// No path — null safety only
fallbackValue(value, null, "default")
// Untyped data
fallbackValue(anyValue, "path.to.something", "default")