Replace the loose NotificationDefaults intermediate type and 'as NotificationFormData' cast with an exhaustive buildDefaults() helper that narrows each branch of the discriminated union explicitly. TypeScript now infers the return type correctly from the discriminated union without any casts, satisfying strong typing for all channels (email, slack, discord, webhook, pager_duty, teams, matrix, telegram).
77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
import { useMemo } from "react";
|
|
import { notificationSchema } from "@/Validation/notifications";
|
|
import type { NotificationFormData } from "@/Validation/notifications";
|
|
import type { Notification } from "@/Types/Notification";
|
|
|
|
interface UseNotificationFormOptions {
|
|
data?: Notification | null;
|
|
}
|
|
|
|
function buildDefaults(data: Notification | null): NotificationFormData {
|
|
if (data?.type === "matrix") {
|
|
return {
|
|
type: "matrix",
|
|
notificationName: data.notificationName || "",
|
|
homeserverUrl: data.homeserverUrl || "",
|
|
roomId: data.roomId || "",
|
|
accessToken: data.accessToken || "",
|
|
};
|
|
}
|
|
if (data?.type === "telegram") {
|
|
return {
|
|
type: "telegram",
|
|
notificationName: data.notificationName || "",
|
|
address: data.address || "",
|
|
accessToken: data.accessToken || "",
|
|
};
|
|
}
|
|
if (data?.type === "slack") {
|
|
return {
|
|
type: "slack",
|
|
notificationName: data.notificationName || "",
|
|
address: data.address || "",
|
|
};
|
|
}
|
|
if (data?.type === "discord") {
|
|
return {
|
|
type: "discord",
|
|
notificationName: data.notificationName || "",
|
|
address: data.address || "",
|
|
};
|
|
}
|
|
if (data?.type === "webhook") {
|
|
return {
|
|
type: "webhook",
|
|
notificationName: data.notificationName || "",
|
|
address: data.address || "",
|
|
};
|
|
}
|
|
if (data?.type === "pager_duty") {
|
|
return {
|
|
type: "pager_duty",
|
|
notificationName: data.notificationName || "",
|
|
address: data.address || "",
|
|
};
|
|
}
|
|
if (data?.type === "teams") {
|
|
return {
|
|
type: "teams",
|
|
notificationName: data.notificationName || "",
|
|
address: data.address || "",
|
|
};
|
|
}
|
|
// Default: email (covers both data === null and data.type === "email")
|
|
return {
|
|
type: "email",
|
|
notificationName: data?.notificationName || "",
|
|
address: data?.address || "",
|
|
};
|
|
}
|
|
|
|
export const useNotificationForm = ({ data = null }: UseNotificationFormOptions = {}) => {
|
|
return useMemo(() => {
|
|
const defaults = buildDefaults(data);
|
|
return { schema: notificationSchema, defaults };
|
|
}, [data]);
|
|
};
|