entangle.ts
Version:
A declarative, event-driven framework for orchestrating business logic in TypeScript & Node.js applications.
71 lines (70 loc) • 2.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Notation = void 0;
/**
* A type-safe, fluent builder for creating dot-notation accessors for nested objects.
* It provides compile-time safety and autocompletion for object properties and array indices.
*
* @template TRoot The type of the root object where the search begins.
* @template TCurrent The type of the value at the current point in the notation chain.
*/
class Notation {
constructor(currentNotation = '') {
this._notation = currentNotation;
}
/**
* Starts building a new type-safe notation path.
* @template TData The type of the data object this notation will operate on.
*/
static create(currentNotation) {
return new Notation(currentNotation);
}
/**
* Appends a property access to the notation path.
* The compiler will only allow keys that exist on the current type.
* @param prop The key of the property to access.
* @returns A new Notation instance focused on the type of the accessed property.
*/
property(prop) {
const newNotation = this._notation ? `${this._notation}.${String(prop)}` : String(prop);
return new Notation(newNotation);
}
/**
* Appends an index access to the notation path.
* This method should be used when the current focus is an array.
* @param i The index of the array to access.
* @returns A new Notation instance focused on the type of the array element.
*/
index(i) {
const newNotation = this._notation ? `${this._notation}.${i}` : String(i);
return new Notation(newNotation);
}
/**
* @returns The raw, built notation string (e.g., 'user.profile.name').
*/
get() {
return this._notation;
}
/**
* Safely executes the notation against a root data object.
* The return type is safely inferred from the chain of calls.
* @param data The root object to retrieve the value from. It must match the TRoot type.
* @returns The resolved value, or `undefined` if the path is not found.
*/
getData(data) {
if (!this._notation) {
return data;
}
const parts = this._notation.split('.');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let currentValue = data;
for (const part of parts) {
if (typeof currentValue !== 'object' || currentValue === null) {
return undefined;
}
currentValue = currentValue[part];
}
return currentValue;
}
}
exports.Notation = Notation;