Complete Reflect API for meta-programming, proxy operations, and dynamic property manipulation with enhanced error handling and type safety.
Complete set of Reflect methods for meta-programming operations.
/**
* Reflect API for meta-programming and proxy operations
*/
interface Reflect {
/**
* Calls a target function with arguments as specified by the argumentsList parameter
* @param target - The target function to call
* @param thisArgument - The value of this provided for the call to target
* @param argumentsList - Array-like object specifying arguments
*/
apply<T, A extends readonly any[], R>(
target: (this: T, ...args: A) => R,
thisArgument: T,
argumentsList: Readonly<A>
): R;
/**
* Acts like the new operator, but as a function
* @param target - The target function to act as the constructor
* @param argumentsList - Array-like object specifying arguments
* @param newTarget - The constructor whose prototype should be used
*/
construct<A extends readonly any[], R>(
target: new (...args: A) => R,
argumentsList: Readonly<A>,
newTarget?: any
): R;
/**
* Defines a property on an object
* @param target - The target object
* @param propertyKey - The name of the property to define
* @param attributes - The attributes for the property being defined
*/
defineProperty(
target: object,
propertyKey: PropertyKey,
attributes: PropertyDescriptor
): boolean;
/**
* Deletes a property from an object
* @param target - The target object
* @param propertyKey - The name of the property to delete
*/
deleteProperty(target: object, propertyKey: PropertyKey): boolean;
/**
* Gets a property value from an object
* @param target - The target object
* @param propertyKey - The name of the property to get
* @param receiver - The value of this provided for the call if a getter is encountered
*/
get<T extends object, P extends PropertyKey>(
target: T,
propertyKey: P,
receiver?: unknown
): T[P];
/**
* Gets the property descriptor for a property of an object
* @param target - The target object
* @param propertyKey - The name of the property
*/
getOwnPropertyDescriptor(
target: object,
propertyKey: PropertyKey
): PropertyDescriptor | undefined;
/**
* Returns the prototype of an object
* @param target - The target object
*/
getPrototypeOf(target: object): object | null;
/**
* Determines whether an object has a property
* @param target - The target object
* @param propertyKey - The name of the property to check
*/
has(target: object, propertyKey: PropertyKey): boolean;
/**
* Determines if an object is extensible
* @param target - The target object
*/
isExtensible(target: object): boolean;
/**
* Returns an array of the target object's own property keys
* @param target - The target object
*/
ownKeys(target: object): (string | symbol)[];
/**
* Prevents new properties from being added to an object
* @param target - The target object
*/
preventExtensions(target: object): boolean;
/**
* Sets a property value on an object
* @param target - The target object
* @param propertyKey - The name of the property to set
* @param value - The value to set
* @param receiver - The value of this provided for the call if a setter is encountered
*/
set<T extends object, P extends PropertyKey>(
target: T,
propertyKey: P,
value: T[P],
receiver?: any
): boolean;
/**
* Sets the prototype of an object
* @param target - The target object
* @param proto - The new prototype
*/
setPrototypeOf(target: object, proto: object | null): boolean;
}Usage Examples:
import Reflect from 'core-js-pure/stable/reflect';
// Function application
function greet(greeting, name) {
return `${greeting}, ${name}!`;
}
const result = Reflect.apply(greet, null, ['Hello', 'World']); // "Hello, World!"
// Constructor invocation
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
const person = Reflect.construct(Person, ['Alice', 30]); // Person { name: 'Alice', age: 30 }
// Property operations
const obj = { x: 1, y: 2 };
// Get property
const x = Reflect.get(obj, 'x'); // 1
// Set property
Reflect.set(obj, 'z', 3); // true, obj is now { x: 1, y: 2, z: 3 }
// Check property existence
const hasY = Reflect.has(obj, 'y'); // true
// Get property descriptor
const descriptor = Reflect.getOwnPropertyDescriptor(obj, 'x');
// { value: 1, writable: true, enumerable: true, configurable: true }
// Define property
Reflect.defineProperty(obj, 'computed', {
get() { return this.x + this.y; },
enumerable: true,
configurable: true
}); // true
// Delete property
Reflect.deleteProperty(obj, 'z'); // true
// Get all keys
const keys = Reflect.ownKeys(obj); // ['x', 'y', 'computed']
// Prototype operations
const proto = Reflect.getPrototypeOf(obj); // Object.prototype
const newProto = { customMethod() { return 'custom'; } };
Reflect.setPrototypeOf(obj, newProto); // true
// Extensibility
const isExtensible = Reflect.isExtensible(obj); // true
Reflect.preventExtensions(obj); // true
const stillExtensible = Reflect.isExtensible(obj); // falseimport Reflect from 'core-js-pure/stable/reflect';
// Create a logging proxy using Reflect
function createLoggingProxy(target, name) {
return new Proxy(target, {
get(target, prop, receiver) {
console.log(`Getting ${name}.${String(prop)}`);
return Reflect.get(target, prop, receiver);
},
set(target, prop, value, receiver) {
console.log(`Setting ${name}.${String(prop)} = ${value}`);
return Reflect.set(target, prop, value, receiver);
},
has(target, prop) {
console.log(`Checking if ${name} has ${String(prop)}`);
return Reflect.has(target, prop);
},
deleteProperty(target, prop) {
console.log(`Deleting ${name}.${String(prop)}`);
return Reflect.deleteProperty(target, prop);
}
});
}
const user = { name: 'Alice', email: 'alice@example.com' };
const loggedUser = createLoggingProxy(user, 'user');
loggedUser.name; // Logs: "Getting user.name"
loggedUser.age = 30; // Logs: "Setting user.age = 30"
'email' in loggedUser; // Logs: "Checking if user has email"
delete loggedUser.email; // Logs: "Deleting user.email"import Reflect from 'core-js-pure/stable/reflect';
// Safe property getter with default values
function safeGet(obj, path, defaultValue = undefined) {
const keys = path.split('.');
let current = obj;
for (const key of keys) {
if (!Reflect.has(current, key)) {
return defaultValue;
}
current = Reflect.get(current, key);
}
return current;
}
// Safe property setter
function safeSet(obj, path, value) {
const keys = path.split('.');
const lastKey = keys.pop();
let current = obj;
// Navigate to parent object
for (const key of keys) {
if (!Reflect.has(current, key) || typeof current[key] !== 'object') {
Reflect.set(current, key, {});
}
current = Reflect.get(current, key);
}
return Reflect.set(current, lastKey, value);
}
const data = {
user: {
profile: {
name: 'Alice'
}
}
};
// Safe access
const name = safeGet(data, 'user.profile.name'); // 'Alice'
const missing = safeGet(data, 'user.settings.theme', 'default'); // 'default'
// Safe setting
safeSet(data, 'user.settings.theme', 'dark');
console.log(data.user.settings.theme); // 'dark'import Reflect from 'core-js-pure/stable/reflect';
// Dynamic method caller with error handling
function callMethod(obj, methodName, ...args) {
if (!Reflect.has(obj, methodName)) {
throw new Error(`Method '${methodName}' does not exist`);
}
const method = Reflect.get(obj, methodName);
if (typeof method !== 'function') {
throw new Error(`'${methodName}' is not a function`);
}
return Reflect.apply(method, obj, args);
}
// Object factory using Reflect.construct
function createInstance(Constructor, ...args) {
if (typeof Constructor !== 'function') {
throw new Error('Constructor must be a function');
}
return Reflect.construct(Constructor, args);
}
class Calculator {
add(a, b) { return a + b; }
multiply(a, b) { return a * b; }
}
const calc = new Calculator();
// Dynamic method calls
const sum = callMethod(calc, 'add', 5, 3); // 8
const product = callMethod(calc, 'multiply', 4, 7); // 28
// Dynamic instance creation
const newCalc = createInstance(Calculator); // new Calculator()
const array = createInstance(Array, 1, 2, 3); // [1, 2, 3]import Reflect from 'core-js-pure/stable/reflect';
// Property validator using Reflect
function createValidatedObject(validators = {}) {
const obj = {};
return new Proxy(obj, {
set(target, prop, value) {
const validator = validators[prop];
if (validator && !validator(value)) {
throw new Error(`Invalid value for property '${String(prop)}'`);
}
return Reflect.set(target, prop, value);
},
defineProperty(target, prop, descriptor) {
const validator = validators[prop];
if (validator && descriptor.value !== undefined && !validator(descriptor.value)) {
throw new Error(`Invalid value for property '${String(prop)}'`);
}
return Reflect.defineProperty(target, prop, descriptor);
}
});
}
// Create validated user object
const validatedUser = createValidatedObject({
name: value => typeof value === 'string' && value.length > 0,
age: value => typeof value === 'number' && value >= 0 && value < 150,
email: value => typeof value === 'string' && value.includes('@')
});
validatedUser.name = 'Alice'; // OK
validatedUser.age = 30; // OK
validatedUser.email = 'alice@example.com'; // OK
try {
validatedUser.age = -5; // Throws error
} catch (e) {
console.error(e.message); // "Invalid value for property 'age'"
}