I have a number of different email templates that each have different parameters.
I can define a type for each template:
type TemplateType = 'welcomeEmail' | 'referralEmail' | 'loginEmail'
And for each template I can define parameters:
interface WelcomeEmail {
firstName: string;
lastName: string;
...
}
I a can then define an EmailTemplate interface:
interface EmailTemplate {
template: TemplateType;
params: WelcomeEmail | ReferralEmail | LoginEmail;
}
Is there a way to type this so that when the template is 'welcomeEmail' the params
type is WelcomeEmail
?
It can be done in recent versions of Typescript if you change your types around a bit. This works by sourcing the TemplateType
and the EmailTemplate
from the same EmailTemplates
type. Typescript knows that members of TemplateType
correspond to keys of EmailTemplates
, and it can use that relationship to find the value types that are associated with a given TemplateType
.
type EmailTemplates = {
welcomeEmail: {
firstName: string;
lastName: string;
};
referralEmail: {
referrer: string;
};
}
type TemplateType = keyof EmailTemplates;
type EmailTemplate<T extends TemplateType> = {
template: T;
params: EmailTemplates[T]
}
const myEmail: EmailTemplate<'referralEmail'> = {
template: 'referralEmail',
params: { referrer: 'test' },
}
There may be some way to infer the TemplateType instead of having to pass it in as a generic type parameter, but I'm not sure how.
type TemplateType = 'welcomeEmail' | 'referralEmail' | 'loginEmail' interface WelcomeEmail { firstName: string; lastName: string; // ... } interface WelcomeEmailTemplate { template: 'welcomeEmail'; params: WelcomeEmail; } interface ReferralEmailTemplate { // ... } interface LoginEmailTemplate { // ... } type EmailTemplate = WelcomeEmailTemplate | ReferralEmailTemplate | LoginEmailTemplate const myEmail: EmailTemplate = { template: 'welcomeEmail', params: { // then type checking and hinting is here for WelcomeEmailTemplate }, }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.