Обрабатывать объекты со свойствами, которые могут быть нескольких типов в Angular

Я пытаюсь создать экран поиска, который использует вкладки для переключения между различными методами ввода, но я сталкиваюсь с ошибкой Typescript, потому что мой базовый объект допускает несколько типов, а мой пользовательский компонент ввода - нет.

В родительском компоненте у меня есть массив объектов типа Tab для определения всех вкладок.

export interface Tab {
  id: string,
  name: string,
  desc: string,
  type: string,
  isCurrent: boolean,
  value: string | number | Checkbox[] | IDate
}

Я перебираю этот массив и создаю другой HTML в зависимости от типа вкладки.

Однако, поскольку значение может быть несколькими разными типами данных, я получаю ошибки, когда пытаюсь создать флажки, потому что мне нужно перебрать массив. например *ngFor выдает ошибку, потому что tab.value может быть не массивом, а числом и т. д.

      <div class = "govuk-form-group" *ngIf = "tab.type === 'checkbox'">
        <fieldset class = "govuk-fieldset" aria-describedby = "{tab.id + 'hint'}">
          <div class = "govuk-checkboxes" data-module = "govuk-checkboxes">
            <div class = "govuk-checkboxes__item" *ngFor = "let checkbox of tab.value">
              <input class = "govuk-checkboxes__input" id = "{{checkbox.id}}" name = "{{checkbox.id}}" type = "checkbox" [(ngModel)] = "checkbox.selected">
              <label class = "govuk-label govuk-checkboxes__label" for = "{{checkbox.id}}">
                {{checkbox.name}}
              </label>
            </div>
          </div>
        </fieldset>
      </div>

Я попытался использовать дочерний компонент, в результате чего Tab.value переопределяется в дочернем элементе только как тип Checkbox[] и передает объект вкладки от родителя к дочернему. Но затем я получаю сообщение об ошибке, говорящее, что одно не может быть назначено другому, что имеет смысл, поскольку значение может содержать разные типы в обоих интерфейсах.

Есть ли способ, которым я могу выполнить проверку типа, не прибегая к использованию any?

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот способ, которым вы могли бы справиться с этим, сохраняя свой html точно таким, какой он есть, и просто меняя типы. Это немного многословно, но позволяет TypeScript вывести тип свойства value из значения свойства type.

export type Tab = StringTab | NumberTab | DateTab | CheckboxTab;

interface TabBase {
    id: string,
    name: string,
    desc: string,
    isCurrent: boolean
}

interface StringTab extends TabBase {
    type: "string",
    value: string
}

interface NumberTab extends TabBase {
    type: "number",
    value: number
}

interface DateTab extends TabBase {
    type: "date",
    value: IDate
}

interface CheckboxTab extends TabBase {
    type: "checkbox",
    value: Checkbox[]
}

Я доволен многословием. Действительно хорошее решение. Спасибо.

jdez 03.04.2023 15:50

Другие вопросы по теме