Как создать тип со всеми свойствами из Type1 или всеми свойствами из Type2 в Typescript?

#typescript

Вопрос:

У меня есть такой код:

 interface Notification {
  message: TemplatedEmail amp; Email, //current attempt which doesnt do what I want
}

interface Destination {
  ccAddresses?: string[],
  bccAddresses?: string[],
  toAddresses: string[]
}

interface TemplatedEmail {
  destination: Destination,
  source: string,
  template: string,
  templateData: any,
  replyToAddresses?: string[]
}

interface Email {
  destination: Destination,
  source: string,
  body: string,
  subject: string,
  replyToAddresses?: string[]
}
 

Я хочу message , чтобы свойство of Notifications имело тип Email или TemplatedEmail , под этим я подразумеваю, что либо все свойства (необязательно, конечно, можно пропустить) Email должны быть доступны в message , либо все свойства TemplatedEmail . С типами объединения я могу получить доступ только к свойствам, общим для обоих типов, а с типами пересечения я получаю все свойства обоих типов.

С моим текущим кодом что-то подобное не работает:

 const x: Notification = { 
    message: {
          destination: { toAddresses: [ "" ] },
          source: "",
          body: "",
          subject: ""
    }
};
 

Он жалуется, что свойства template и templateData отсутствуют x .

Ответ №1:

Одним из способов было бы использовать дискриминационный союз, но это немного изменило бы структуру вашего сообщения:

 type XType = TemplateNotification | EmailNotification;

interface TemplateNotification {
  kind: 'template',
  message: TemplatedEmail
}

interface EmailNotification {
  kind: 'email',
  message: Email
}

const x: XType = { 
    kind: 'email',
    message: {
          destination: { toAddresses: [ "" ] },
          source: "",
          body: "",
          subject: ""
    }
};
 

пример игровой площадки здесь

Комментарии:

1. Ваш код не завершен, закончите его, а затем сами увидите ошибку, ссылка слишком длинная, поэтому я не могу поместить ее в комментарий.

2. Почему ты переоделся Notification в INotification ? В вашем обновленном коде, когда я это делаю console.log(x.message.body); , я получаю Property 'body' does not exist on type 'TemplatedEmail | Email'. Property 'body' does not exist on type 'TemplatedEmail'.

3. Типы объединения предоставляют доступ только к свойствам, доступным в обоих типах.

4. уведомление об интерфейсе зарезервировано в TS Playground и поступает из lib.dom.d.ts, поэтому мне пришлось изменить его на INotification. У вас не было бы этой проблемы в вашем модуле. Теперь я прочитал, что вы пытались использовать union, поэтому я отредактировал свой ответ, чтобы лучше соответствовать вашим требованиям. надеюсь, это поможет

5. Это именно то, что мне было нужно. Спасибо. Я подожду и посмотрю, есть ли какие-то другие способы достичь этого, а затем приму это как ответ.