ProxySignal

Creates a wrapper around a signal that intercepts get and set operations.

Usage

Provides explicit control over signal get (dependency tracking) and set (update triggering) operations, while preserving the standard WritableSignal or Signal interface.

Update logic customization enables you to define custom behavior for set() or update() calls on the created signal. For example, to implement custom scheduling:

angular-ts
import { signal } from '@angular/core';
import { proxySignal } from '@signality/core';

function debouncedSignal<T>(initialValue: T, ms: number): WritableSignal<T> {
  const source = signal(initialValue);
  let timeoutId: ReturnType<typeof setTimeout>;

  return proxySignal(source, {
    set: (value, source) => { 
      clearTimeout(timeoutId);  
      timeoutId = setTimeout(() => source.set(value), ms); 
    } 
  });
}

Now you can use debouncedSignal to create signals with delayed updates:

angular-ts
const search = debouncedSignal('', 300);
search.set('query'); // actual update happens after 300ms of inactivity

Note

Signality uses proxySignal internally in utilities like Debounced and Throttled to implement scheduling behavior.

Parameters

ParameterTypeDescription
sourceSignal<T> or WritableSignal<T>Source signal to wrap
handlerProxySignalHandler<T, R>Handler with optional get/set transformations
optionsPick<CreateSignalOptions<R>, 'equal'>Optional configuration (see Options below)

Options

equal applies to the proxy handler, not the source signal

The equal option does not propagate to the original source signal. It is used exclusively by the proxy's set and update methods to compare transformed values — that is, the result of calling handler.get on the current source value.

By default, Object.is is used.

OptionTypeDescription
equalValueEqualityFn<T>Custom equality function

Return Value

  • When passed a writable signal → returns WritableSignal<T>
  • When passed a readonly signal → returns Signal<T>

Examples

Type transformation

Use get + set together for bidirectional transformation:

angular-ts
import { signal } from '@angular/core';
import { proxySignal } from '@signality/core';

const source = signal('a,b,c');
const proxy = proxySignal(source, {
  get: s => s().split(','), // string → string[]
  set: (v, s) => s.set(v.join(',')) // string[] → string
});

proxy(); // ['a', 'b', 'c']
proxy.set(['x', 'y']); // source becomes 'x,y'
proxy(); // ['x', 'y']

Type Definitions

typescript
export type ProxySignalHandler<T, R = T> =
  | { readonly get: (source: Signal<T>) => R; readonly set: (value: R, source: WritableSignal<T>) => void }
  | { readonly get: (source: Signal<T>) => T; readonly set: (value: T, source: WritableSignal<T>) => void }
  | { readonly get: (source: Signal<T>) => R; readonly set?: never }
  | { readonly get?: never; readonly set: (value: T, source: WritableSignal<T>) => void }
  | { readonly get?: never; readonly set?: never };

function proxySignal<T>(
  source: WritableSignal<T>,
  handler: { get: (source: Signal<T>) => T; set: (value: T, source: WritableSignal<T>) => void },
  options?: Pick<CreateSignalOptions<T>, 'equal'>
): WritableSignal<T>;

function proxySignal<T, R>(
  source: WritableSignal<T>,
  handler: { get: (source: Signal<T>) => R; set: (value: R, source: WritableSignal<T>) => void },
  options?: Pick<CreateSignalOptions<R>, 'equal'>
): WritableSignal<R>;

function proxySignal<T>(
  source: WritableSignal<T>,
  handler: { get: (source: Signal<T>) => T; set?: never },
  options?: never
): WritableSignal<T>;

function proxySignal<T, R>(
  source: Signal<T>,
  handler: { get: (source: Signal<T>) => R; set?: never },
  options?: never
): Signal<R>;

function proxySignal<T>(
  source: WritableSignal<T>,
  handler: { get?: never; set: (value: T, source: WritableSignal<T>) => void },
  options?: Pick<CreateSignalOptions<T>, 'equal'>
): WritableSignal<T>;

function proxySignal<T>(
  source: WritableSignal<T>,
  handler: { get?: never; set?: never },
  options?: never
): WritableSignal<T>;

function proxySignal<T>(
  source: Signal<T>,
  handler: { get?: never; set?: never },
  options?: never
): Signal<T>;
Edit this page on GitHub Last updated: Apr 27, 2026, 21:56:11