This one has been puzzling me for a while, trying to create a type-safe email service.
I have an enum of possible template names:
enum TemplateName {
EXAMPLE_TEMPLATE = "EXAMPLE TEMPLATE"
...
}
I have an object of default settings per template:
type EmailConfig<X = React.ComponentType> = {
html: X
subject: string
...
}
type EmailMapping: EmailConfig = {
[key in TemplateName]: EmailConfig
}
const Emails = {
[TemplateName.EXAMPLE_TEMPLATE]: {
html: TestTemplate, // THIS IS A REACT FUNCTIONAL COMPONENT
subject: "This is a test",
...rest
}
...
}
My Templates look like so:
export interface TestTemplateProps {
title?: string
firstName?: string
preview?: string
headline?: string
site?: string
...
}
export const TestTemplate: React.FC<TestTemplateProps> = ({
title = 'Test Email',
site = 'My Website',
preview = 'Important Information from My Site',
firstName = 'there',
headline,
children,
}) => {
return (
...
)
}
I have a generic function I want to be able to pass in an enum value and all the props of the Component that relates to that enum value.
FOR EXAMPLE
sendEmail(TemplateName.EXAMPLE_TEMPLATE, { ... })
Where { ... } is typed to TestTemplateProps interface
My current attempt at sendEmail looks like this:
async sendEmail<X extends keyof EmailMapping>(
template: X,
opts: React.ComponentProps<typeof Emails[X]['html']>
) {
...
}
I've tried just playing around (honestly I am just guessing at what to change at this point) and this is the closest I have come so far.
When I call sendEmail with above code, it forced me to pass one of the Enums, but then in the opts the only "typing" that appears is "children?" and none of the other properties in the TestTemplateProps so I think I'm close!
TIA