I have a code like this
type ScanSheetEvents =
| { type: "updateStationsList"; stationsList: StationCodeList }
| { type: "reAskPermissions" };
And i want to ensure that some type if of given type of throw and get type inference (something like this)
(_, event) => {
throwIfNotEvent(event, "updateStationsList");
return event.stationsList;
I started to write something like that, but I'm not able to make it work… I want auto-completion on event when type is ensured.
function throwIfNotEvent(
event: ScanSheetEvents,
eventType: ScanSheetEvents["type"],
): event is … {
if (event.type !== eventType) throw Error("Unexpected event" event.type);
}
maybe someone could help me?
Thanks
CodePudding user response:
You want something like:
function throwIfNotEvent<T extends ScanSheetEvents['type']>(
event: ScanSheetEvents,
eventType: T,
): asserts event is ScanSheetEvents & { type: T } {
if (event.type !== eventType) throw Error("Unexpected event" event.type);
}
This function now has a generic type parameter T
which is constrained by the union of type
properties in ScanSheetEvents
. See Generics
The return value is asserts event is ...
which means that an exception is expected to be thrown if event
is not of the stated type. See Assertion Functions.
ScanSheetEvents & { type: T }
means that the union of all events is filtered down to just the ones that match whatever type was passed as eventType
. See Intersection Types
And now this function will work without complaint:
const fn = (event: ScanSheetEvents) => {
throwIfNotEvent(event, "updateStationsList");
return event.stationsList; // works
}