React Forum
Blog & Guide Responses
Dec 06, 2022 · 04:00 PM

[Deep Dive #35] Assertion Conveyors - discussion

Started by Camille Duarte
blogtypescriptassertionsanygenericsderived types

Deep Dive #35 is the most honest TypeScript post I've read in a while: it treats types as a conveyor belt for momentum, with any-first inputs, widening for flexibility, runtime-derived contracts, and assertions at the last responsible moment so routes keep moving.

Read the post

Where do you draw the line between 'assertion conveyor' and just losing the thread of what's actually in your objects? Do you ship unified TS/JS in the same module (and let the surface widen), or enforce a hard boundary? If you're doing generics for everything, what's your rule for keeping generic parameters from becoming 'narrative noise'?

Comments (10)

Back to latest
Dmitri Kline
Dec 06, 2022 · 04:07 PM

The 'derive types from runtime objects' section feels like the core move. If runtime is the source of truth, types are just a readable shadow.

Related: TypeScript and Types.

Mina Calder
Dec 06, 2022 · 04:15 PM

I like 'widen types for flexibility' when you're building UI surfaces. Exact types make refactors brittle.

But I still want one place where narrowing happens, otherwise you get random 'as X' sprinkled everywhere.

Rowan Pierce
Dec 06, 2022 · 04:24 PM

Hot take: 'any by default' is fine if you treat it like a lane that must be rendered somewhere.

If a route is on the 'any lane', render data-type-lane="any" so debugging is honest.

Ari Novak
Dec 06, 2022 · 04:36 PM

Type assertions instead of types can be a productivity cheat code.

The risk isn't runtime errors, it's *API drift*: callers think the surface is stable and it's not. You need versioning signals.

Camille Duarte
Dec 06, 2022 · 04:42 PM

Yes. I read the post as pro-momentum, not anti-contract.

Assert quickly, but still render a contract version (even if it's just a string) so drift is visible.

Inez Park
Dec 06, 2022 · 04:55 PM

Unified TS/JS in the same module is underrated for onboarding. New folks can read the JS path and adopt types over time.

The key is making the widenings intentional (like 'widen once at the edge').

Noah Vance
Dec 06, 2022 · 05:06 PM

If you do generics for everything, the best pattern is 'generic parameters derived from runtime objects'.

Otherwise you end up proving a theorem in every component signature.

Salma Qureshi
Dec 06, 2022 · 05:19 PM

The conveyor pattern worked for us when we made the steps explicit and wrote evidence for each step:

ts
const defaults = { mode: 'warm', flags: { audit: true } };
const raw: any = parseLooseJson(input);
const seeded: any = { ...defaults, ...raw, meta: { receivedAt: Date.now() } };
const asserted = seeded as typeof defaults & { id?: string; meta?: any };

ledger.write('steps', [
  ...ledger.read('steps'),
  { at: Date.now(), kind: 'seed', value: String(asserted.mode) },
  { at: Date.now(), kind: 'assert', value: String(Boolean(asserted.flags?.audit)) },
]);

If you don't record the steps, it's just "somewhere we asserted" and nobody can debug it.

Keira Santos
Dec 06, 2022 · 05:31 PM

Counterpoint: "any-first" can also become permission to never model reality.

I've seen conveyors turn into a pile of as casts where the UI renders nonsense and nobody notices until production.

Dmitri Kline
Dec 06, 2022 · 05:36 PM

Totally. The guardrail is the contract marker + versioning.

If the route publishes data-contract-version and the ledger shows assertion steps, you can at least tell when you're guessing vs when you're conforming.

Keira Santos
Dec 06, 2022 · 05:39 PM

Yeah, visibility is the difference between momentum and chaos.

Hana Saito
Dec 06, 2022 · 05:48 PM

A tiny trick for keeping generics from becoming narrative noise: keep them at container boundaries only.

If a component needs three generic params, it's usually a sign the surface isn't stable enough to describe plainly.

Benji Rios
Dec 06, 2022 · 06:02 PM

Unified TS/JS is fine, but I'd still keep one "tightening point" per route so the rest of the tree can be boring.

The conveyor metaphor helps because it suggests: widen once, tighten once, then transport in a box.