admin管理员组

文章数量:1420073

I have a number of different email templates that each have different parameters.

I can define a type for each template:

type TemplateType = 'weleEmail' | 'referralEmail' | 'loginEmail'

And for each template I can define parameters:

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

I a can then define an EmailTemplate interface:

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

Is there a way to type this so that when the template is 'weleEmail' the params type is WeleEmail?

I have a number of different email templates that each have different parameters.

I can define a type for each template:

type TemplateType = 'weleEmail' | 'referralEmail' | 'loginEmail'

And for each template I can define parameters:

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

I a can then define an EmailTemplate interface:

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

Is there a way to type this so that when the template is 'weleEmail' the params type is WeleEmail?

Share Improve this question asked Jan 30, 2020 at 5:20 ljenkinsljenkins 1432 silver badges11 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

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 = {
  weleEmail: {
    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 = 'weleEmail' | 'referralEmail' | 'loginEmail'

interface WeleEmail {
  firstName: string;
  lastName: string;
  // ...
}

interface WeleEmailTemplate {
  template: 'weleEmail';
  params: WeleEmail;
}

interface ReferralEmailTemplate {
  // ...
}

interface LoginEmailTemplate {
  // ...
}

type EmailTemplate = WeleEmailTemplate | ReferralEmailTemplate | LoginEmailTemplate

const myEmail: EmailTemplate = {
  template: 'weleEmail',
  params: {
    // then type checking and hinting is here for WeleEmailTemplate
  },
}

本文标签: javascriptHow to use Typescript to define strongly typed email template parametersStack Overflow