typescript属性“选项”在联合体类型的类型上不存在

时间:2019-01-19 03:11:34

标签: angular typescript union-types

我有几个接口和一个联合类型:

export interface FieldOptions {
  value: string | number;
  viewValue: string;
}

export interface BaseField {
  id: string;
  derived?: boolean;
  required?: boolean;
}

export interface NumberField extends BaseField {
  type: 'number';
  decimals: number;
}
export interface SelectField extends BaseField {
  type: 'select' | 'select-multi';
  options: FieldOptions[];
  source?: string;
}

export type Field = NumberField | SelectField;

据我了解,当我使用联合类型字段Field时,它的主字段可以是Number或Select。

有了这些知识,我的Angular Component中就有了一个函数

getField( key: string ): Field {
  return this.fields.filter( el => el.id === key )[ 0 ];
}

getFieldVersion2( key: string ): any {
  const field = this.fields.filter( el => el.id === key )[ 0 ];
  if ( (<SelectField>field).options ) {
    return field as SelectField;
  } else {
    return field as Field;
  }
}

仅使用模板中调用的函数getField来获取Field对象,在这种情况下,是使用带有View / viewValues的Options数组的Select,我在TS上遇到了构建错误:

Property 'options' does not exist on type 'Field'.
   Property 'options' does not exist on type 'NumberField'.

据我了解,字段是数字或选择的并集类型。其中一个具有options属性,另一个则没有。

因此,我创建了getFieldVersion2来希望解决该问题。但是,除非我将any添加为函数的结果类型,否则它将触发生成错误。

使用options的模板会触发编译错误:

<mat-form-field  class="input">
  <mat-select formControlName="state">
    <mat-option *ngFor="let option of getField( 'state' ).options" [value]="option.value">
       {{option.viewValue}}
    </mat-option>
  </mat-select>
</mat-form-field>

这是怎么回事,我该怎么做呢?

1 个答案:

答案 0 :(得分:1)

您创建了一个没有“ options”属性的界面。然后,将“字段”类型设置为等于该接口(或可能等于另一个具有“选项”属性的接口)。

然后,您尝试调用可能存在或不存在的“ options”属性。这就是为什么您在编译时收到ts错误的原因。

将返回类型切换为“ any”是可行的,因为编译器不会尝试猜测您要返回的对象的类型(因此,“ options”将是有效的属性,因此不应该引发任何错误,这是合理的)。

如果要在“字段”类型上调用“选项”属性,则在尝试编译ts脚本之前,应确保该属性存在。

也许将方法更新为“ getSelectField”和“ getNumberField”会是一个更好的选择。...但是,当然,您可以通过多种方式来处理此问题。