Size / Priority
- Size: No change — reference example, no work required.
- Category: C.1 Pattern-Matching — documentation / codebase-style item.
Affected files
src/crdt/DistributedData.ts:49-71 — decodeCrdt discriminated-union dispatch.
Status — no implementation needed
This issue is intentionally a no-op. decodeCrdt already uses a TypeScript-exhaustive switch:
export function decodeCrdt(json: CrdtJson): Crdt<any> {
switch (json.kind) {
case 'GCounter': return GCounter.fromJSON(json);
case 'PNCounter': return PNCounter.fromJSON(json);
case 'GSet': return GSet.fromJSON<unknown>(json);
case 'ORSet': return ORSet.fromJSON<unknown>(json);
case 'LWWRegister': return LWWRegister.fromJSON<unknown>(json);
case 'GCounterMap': return GCounterMap.fromJSON<unknown>(json);
case 'LWWMap': return LWWMap.fromJSON<unknown, unknown>(json);
case 'MVRegister': return MVRegister.fromJSON<unknown>(json);
case 'ORMap': return ORMap.fromJSON<unknown, Crdt<any>>(json, /* ... */);
default: {
const _exhaustive: never = json;
throw new Error(`unknown crdt kind: ${(_exhaustive as { kind: string }).kind}`);
}
}
}
The const _exhaustive: never = json assignment in the default branch is the compile-time exhaustiveness guard — if a new variant is added to CrdtJson without updating this switch, TypeScript reports an error here because json would no longer be assignable to never.
This is functionally equivalent to match().exhaustive() and arguably faster (native switch vs library function call).
Why this is the "reference example" in the catalog
Other items in C.1 (#230, #232–#247) propose converting if-chains and instanceof-chains to match().exhaustive() for the same exhaustiveness property. This site demonstrates that vanilla switch + never-assignment achieves the same property when:
- The discriminator is a string literal union (not nominal types — for those,
match is still preferred).
- The arms are simple call dispatches (not multi-clause guards).
For both forms, the exhaustiveness check is what matters. Either is acceptable; the codebase happens to use both.
Action
Acceptance criteria
Size / Priority
Affected files
src/crdt/DistributedData.ts:49-71—decodeCrdtdiscriminated-union dispatch.Status — no implementation needed
This issue is intentionally a no-op.
decodeCrdtalready uses a TypeScript-exhaustive switch:The
const _exhaustive: never = jsonassignment in the default branch is the compile-time exhaustiveness guard — if a new variant is added toCrdtJsonwithout updating this switch, TypeScript reports an error here becausejsonwould no longer be assignable tonever.This is functionally equivalent to
match().exhaustive()and arguably faster (nativeswitchvs library function call).Why this is the "reference example" in the catalog
Other items in C.1 (#230, #232–#247) propose converting if-chains and instanceof-chains to
match().exhaustive()for the same exhaustiveness property. This site demonstrates that vanillaswitch+never-assignment achieves the same property when:matchis still preferred).For both forms, the exhaustiveness check is what matters. Either is acceptable; the codebase happens to use both.
Action
switch(string-literal unions, simple dispatches) vsmatch(nominal types viaP.instanceOf, guard predicates, complex patterns).Acceptance criteria
DistributedData.ts.switchwithout anever-typed default branch in the codebase (would catch any new switch that forgot the guard).