Implemented getSafe method

This commit is contained in:
Kir_Antipov 2023-05-15 09:21:15 +00:00
parent de17c8b440
commit 149430bbe9
3 changed files with 79 additions and 0 deletions

View file

@ -30,4 +30,5 @@ export {
getOwnEntries,
merge,
getSafe,
} from "./object-reflector";

View file

@ -205,3 +205,26 @@ export function merge<T extends unknown[]>(...values: T): UnionToIntersection<T[
}
return result;
}
/**
* Safely retrieves a property value from an object, or returns `undefined` if the property is not accessible.
*
* @template T - The type of the object.
* @template K - The type of the property key.
*
* @param target - The object from which to retrieve the property value.
* @param key - The key of the property to retrieve.
*
* @returns The value of the property if accessible, otherwise `undefined`.
*/
export function getSafe<T, K extends PropertyKey>(target: T, key: K): (K extends keyof T ? T[K] : unknown) | undefined {
if (target === null || target === undefined) {
return undefined;
}
try {
return target[key as string];
} catch {
return undefined;
}
}

View file

@ -9,6 +9,7 @@ import {
getAllValues,
getOwnEntries,
getPropertyDescriptor,
getSafe,
merge,
} from "@/utils/reflection/object-reflector";
@ -195,3 +196,57 @@ describe("merge", () => {
expect(Object.getOwnPropertyDescriptor(merged, "b")).toEqual(Object.getOwnPropertyDescriptor(obj2, "b"));
});
});
describe("getSafe", () => {
it("returns the value of an existing property", () => {
const obj = {
name: "John",
age: 30,
};
expect(getSafe(obj, "name")).toBe("John");
expect(getSafe(obj, "age")).toBe(30);
});
it("handles array indices as keys", () => {
const arr = ["apple", "banana", "cherry"] as const;
expect(getSafe(arr, 0)).toBe("apple");
expect(getSafe(arr, 1)).toBe("banana");
expect(getSafe(arr, 2)).toBe("cherry");
expect(getSafe(arr, 3)).toBeUndefined();
});
it("handles Symbols as keys", () => {
const obj = {
[Symbol.toStringTag]: "Not Object",
};
expect(getSafe(obj, Symbol.toStringTag)).toBe("Not Object");
});
it("returns undefined for non-existent properties", () => {
const obj = {
name: "John",
age: 30,
};
expect(getSafe(obj, "address")).toBeUndefined();
expect(getSafe(obj, "salary")).toBeUndefined();
});
it("returns undefined if accessing the property is not possible", () => {
const obj = {
get name(): string {
throw new Error();
}
};
expect(getSafe(obj, "name")).toBeUndefined();
});
it("returns undefined when the target object is null or undefined", () => {
expect(getSafe(null, "name")).toBeUndefined();
expect(getSafe(undefined, "name")).toBeUndefined();
});
});