typescript 在组件字段中使用联合类型时出现HTML错误

8ljdwjyq  于 2022-11-18  发布在  TypeScript
关注(0)|答案(1)|浏览(161)

我想做一个表单生成器组件,我有如下设计表单字段类:

export type FormField<T, TDropDown = any> =
  | InputFormField<T>
  | DropdownFormField<TemplateStringsArray, TDropDown>;

export interface InputFormField<T> {
  key: Extract<keyof T, string>;
  type: 'string' | 'date' | 'number';
}

export interface DropdownFormField<T, TDropDown> {
  type: 'dropdown';
  key: Extract<keyof T, string>;
  dropdownItems: Observable<TDropDown[]>;
  dropdownItemTitleKey: keyof TDropDown;
  dropdownItemValueKey: keyof TDropDown;
}

因此,我有两种类型的表单字段。如果类型的表单字段是下拉式的,那么下拉项目必须填写,否则,这些字段是不必要的。
在HTML文件中,我使用了如下类型:

<div *ngFor="let item of formFields" nz-col nzXs="24" nzMd="12" nzLg="8">
  <nz-form-item>
    <nz-form-label>
       {{ item.key }}
    </nz-form-label>
    <nz-form-control>
      <ng-container [ngSwitch]="item.type">
        <nz-select
          *ngSwitchCase="'dropdown'"
          [formControlName]="item.key"
          nzShowSearch
        >
          <nz-option
            *ngFor="let option of item.dropdownItems | async"
            [nzLabel]="option[item.dropdownItemTitleKey]"
            [nzValue]="option[item.dropdownItemValueKey]"
          ></nz-option>
        </nz-select>
      </ng-container>
    </nz-form-control>
  </nz-form-item>
</div>

我已经使用 *ngSwitchCase="'dropdown'”来确保项目是下拉式项目,但仍然收到此错误:

Property 'dropdownItems' does not exist on type 'SarmadInputFormField<T>'

定义表单字段类并在组件HTML文件中使用它的正确方法是什么?

bfhwhh0e

bfhwhh0e1#

目前,Angular的模板不支持向下转换类型。这就是为什么即使你使用*ngSwitchCase- Angular也不能确定你的联合类型的正确子类型。
如果它在.ts文件中,您可以使用as关键字将其向下转换但同样,此选项在模板sintax中不可用
你的解决方案是,使用$any()关键字。这是由angular提供的,当你在模板中的类型与正确的类型不匹配时,禁用类型检查。
因此,您的代码应如下所示:

*ngFor="let option of $any(item.dropdownItems | async)"

有关$any()的更多信息,请访问:

相关问题