Ramonda

RMD047 — A @memoized member was given an argument it cannot key on

@memoized
pick(row: Row) {          // reported: a Row cannot be part of a cache key
  return () => this.select(row.id);
}
@memoized
pick(id: string) {        // the way: key on the primitive, read the rest inside
  return () => this.select(id);
}

@memoized caches by the ARGUMENTS, and a cache key can hold a string, a number or a boolean. An object cannot: comparing it by value is not something the cache can do, and keying on its identity would miss every time — a fresh object per render would fill the map and hand back a new handler on every pass, which is the churn the decorator exists to prevent.

Development throws, so the mistake is not shipped. Production builds the handler and moves on without caching that call: the page keeps working and only the memoisation is lost. It used to throw there too, from inside a render, so one handler receiving an object took the whole page down — and which handler that was depended on the data, so it could pass every test and fail for one user.

The code is on the thrown error as well as in the log, the way RMD004 is, so a codebase can be swept for it.

Next