Я пытаюсь создать экран поиска, который использует вкладки для переключения между различными методами ввода, но я сталкиваюсь с ошибкой 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
?
Вот способ, которым вы могли бы справиться с этим, сохраняя свой 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[]
}
Я доволен многословием. Действительно хорошее решение. Спасибо.