Loading docs…
Loading docs…
Creates an exhaustive guard for a union with a shared literal discriminant. The guard selects a branch from the input's discriminant value, then delegates to that branch guard.
The value tuple and branch map must each contain every discriminant value. Pair it with typedStruct to check each branch's fields against its existing TypeScript type.
The discriminant must be a required finite literal string, number, symbol, or boolean property on every union member. Broad string, number, and symbol values are rejected because a branch map cannot represent them exhaustively. Infinite template-literal types are rejected for the same reason. Boolean branches use true and false object keys, which makes ok-based Result types a natural fit.
Discriminants that coerce to the same object key, such as 1 and '1', are rejected because a branch map cannot represent them separately.
For a __proto__ discriminant, use the computed key ['__proto__'] (or a null-prototype map). An uncomputed object-literal key changes the map's prototype instead of creating a branch entry.
import {discriminatedUnion,isNumber,oneOfValues,typedStruct,} from 'is-kit';type Event =| { kind: 'click'; x: number; y: number }| { kind: 'scroll'; delta: number };const eventUnion = discriminatedUnion<Event>();export const isEvent = eventUnion('kind', ['click', 'scroll'], {click: typedStruct<Extract<Event, { kind: 'click' }>>()({kind: oneOfValues('click'),x: isNumber,y: isNumber,}),scroll: typedStruct<Extract<Event, { kind: 'scroll' }>>()({kind: oneOfValues('scroll'),delta: isNumber,}),});isEvent({ kind: 'click', x: 12, y: 24 }); // trueisEvent({ kind: 'hover', target: 'button' }); // false// TypeScript error: the scroll branch is required.eventUnion('kind', ['click', 'scroll'], {click: typedStruct<Extract<Event, { kind: 'click' }>>()({kind: oneOfValues('click'),x: isNumber,y: isNumber,}),});