Skip to content

Instantly share code, notes, and snippets.

@lopezjurip
Last active September 27, 2023 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lopezjurip/510ed0116935417d17c05e3e7392a23c to your computer and use it in GitHub Desktop.
Save lopezjurip/510ed0116935417d17c05e3e7392a23c to your computer and use it in GitHub Desktop.
How to define objects representing webhooks or reducer's actions ( useReducer) as TypeScript definitions to be able to switch/case them up.
/** Action identifiers. */
export const WEBHOOKS_EVENTS = [
"user.created",
"user.updated",
// ...
] as const;
/** Action types. */
export type WebhookEvent = typeof WEBHOOKS_EVENTS[number];
/** Action's payloads, if payload is not declared it will default to `unknown`. */
export interface WebhookPayloads extends Record<WebhookEvent, unknown> {
"user.created": { id: string, created_at: string },
"user.updated": { id: string, updated_at: string },
// ...
}
/** Incoming message with generic type. */
export type Webhook<T extends WebhookEvent> = {
id: string;
type: T;
payload: WebhookPayloads[T];
};
/** Union of all possible incoming messages. */
export type Webhooks = { [T in WebhookEvent]: Webhook<T>; }[WebhookEvent];
/** Guard fuction */
export function VERIFY_WEBHOOK(data: uknown): data is Webhooks {
if (!data.hasOwnProperty("id")) return false;
if (!WEBHOOKS_EVENTS.includes(data["type"])) return false;
// Add necessary checks, eg: verify signature.
return true;
}
async function PROCESS_WEBHOOK(webhook: Webhooks) {
switch (webhook["type"]) {
case "user.created": {
const payload = webhook["payload"]; // has type WebhookPayloads["user.created"]
// ...
}
case "user.updated": {
const payload = webhook["payload"]; // has type WebhookPayloads["user.updated"]
// ...
}
default: {
// ...
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment