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

时间:2020-01-30 05:20:11

标签: javascript typescript types typescript-typings typescript3.0

我有许多不同的电子邮件模板,每个模板都有不同的参数。

我可以为每个模板定义一种类型:

type TemplateType = 'welcomeEmail' | 'referralEmail' | 'loginEmail'

我可以为每个模板定义参数:

interface WelcomeEmail {
  firstName: string;
  lastName: string;
  ...
}

然后我可以定义一个EmailTemplate接口:

interface EmailTemplate {
  template: TemplateType;
  params: WelcomeEmail | ReferralEmail | LoginEmail;
}

是否可以键入此内容,以便在模板为“ welcomeEmail”时,params类型为WelcomeEmail

2 个答案:

答案 0 :(得分:3)

如果您稍稍更改类型,可以在最新版本的Typescript中完成。这是通过从相同的TemplateType类型采购EmailTemplateEmailTemplates来实现的。 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' },
}

也许可以通过某种方式推断出TemplateType,而不必将其作为通用类型参数传入,但是我不确定如何。

答案 1 :(得分:1)

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