Baku Hashimoto

Bi-directional binding

Suppose you have a value a: A, and there’s a system that reactively computes a value b: B from it. The mapping function f: A -> B isn’t necessarily bijective, so its inverse function fInv: B -> A might not be well-defined.
However, to achieve a kind of bi-directional binding, I tried to implement a mechanism like this:

type F = (a: A) => B;
type FInv = (b: B, currentA: A) => A;

That is, the inverse function is defined as a function that takes both a value b: B and the current value currentA: A, then returns a value a such that:

  • f(a) is as close as possible to b
  • a is as close as possible to currentA
  • When the corresponding a for b does not exist, simply return currentA

Example 1: square

const f = (a) => a * a;
const fInv = (b: number, currentA: number) => {
  if (b < 0) return 0;
  return Math.sign(currentA) * Math.sqrt(b);
};

Example 2: floor

const f = Math.floor;
const fInv = (b: number, currentA: number) => {
  if (Math.floor(currentA) === b) return currentA;
  return b;
};

Example 3: Number.toString

const f = (a: number) => a.toString();

const fInv = (b: string, currentA: number) => {
  const parsed = parseFloat(b);
  if (isNaN(parsed)) return currentA;
  return parsed;
};
Some Rights Reserved. (cc) 2026 Baku Hashimoto
This site is generated by Garden.ooo