or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array-operations.mdcollection-types.mderror-types.mdindex.mditerator-helpers.mdmath-utilities.mdobject-methods.mdpromise-utilities.mdreflection-api.mdstring-processing.mdsymbol-management.mdtypedarray-operations.mdweb-apis.md
tile.json

reflection-api.mddocs/

Reflection API

Complete Reflect API for meta-programming, proxy operations, and dynamic property manipulation with enhanced error handling and type safety.

Capabilities

Reflect Static Methods

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); // false

Advanced Patterns

Meta-Programming with Proxies

import 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"

Safe Property Access

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'

Dynamic Method Invocation

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]

Property Validation

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'"
}