简体   繁体   English

如何使用 Typescript 定义强类型电子邮件模板参数?

[英]How to use Typescript to define strongly typed email template parameters?

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:然后我可以定义一个 EmailTemplate 接口:

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 ?有没有办法输入这个,以便当模板是 'welcomeEmail' 时, params类型是WelcomeEmail

It can be done in recent versions of Typescript if you change your types around a bit.如果您稍微更改类型,则可以在最新版本的 Typescript 中完成。 This works by sourcing the TemplateType and the EmailTemplate from the same EmailTemplates type.这是通过从相同的EmailTemplates类型获取TemplateTypeEmailTemplate来实现的。 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 . Typescript 知道TemplateType成员对应于EmailTemplates键,它可以使用这种关系来查找与给定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.可能有一些方法可以推断 TemplateType 而不是必须将它作为泛型类型参数传入,但我不确定如何。

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 }, }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM