full code example#

// define top-level data structure for a mail
interface MailData<T extends keyof MailTypeMap> {
  template_id: MailTypeMap[T]["template_id"];
  data: MailTypeMap[T]["data"];
}

// define types for each template
type MailTypeMap = {
  newcomment: { template_id: "new-comment"; data: { comment: string; author: string; date: Date } };
  unreadmessages: { template_id: "unread-messages"; data: { count: number } };
};

// implementation of the send mail functionality
function sendMail<T extends keyof MailTypeMap>(mailType: T, data: MailData<T>): void {}

// exapmle of usage
sendMail("newcomment", {
  template_id: "new-comment",
  data: { date: new Date(), author: "Max Musterman", comment: "Cats are nice!" },
});

Here is the full code example in action TS Playground Link