---
title: Bi-directional binding
date: 2025-05-20T11:26:12.000Z
updated: 2026-01-08T14:50:58.147Z
url: https://baku89.com/Bi-directional_binding
---

# Bi-directional binding

![](https://wp.baku89.com/wp-content/uploads/2026/07/scrapbox-682c77e6e27e13eece0f7147.png)

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;
};
```

### Related

- [Inverse Evaluation](/Inverse_Evaluation)
- Haskell - Lens / Prism
