typecript Свойство 'options' не существует для типа типа Union - PullRequest
0 голосов
/ 19 января 2019

У меня есть пара интерфейсов и тип объединения:

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;

Поскольку я понимаю, что, когда я использую поле типа объединения, поле может иметь значение Number или Select.

С этим знанием у меня есть функция в моем Угловом Компоненте

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, в данном случае Select с Optionsмассив view / viewValues, я получаю ошибку сборки на TS:

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

В моем понимании Field - это тип объединения Number или Select.У одного из них есть свойство 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 голосов
/ 20 января 2019

Вы создали интерфейс, у которого нет свойства "options". Затем вы устанавливаете свой тип «Поле» равным этому интерфейсу (или потенциально равному другому интерфейсу, у которого есть свойство «options»).

Затем вы пытаетесь вызвать свойство «options», которое может существовать или не существовать. Вот почему вы получаете ошибку ts при компиляции.

Переключение типа возврата на «any» работает, потому что компилятор не будет пытаться угадать тип возвращаемого вами объекта (поэтому вполне вероятно, что «options» будет допустимым свойством и, следовательно, не будет выдано никакой ошибки).

Если вы собираетесь вызывать свойство "options" для типа "Field", вы должны убедиться, что оно существует, прежде чем пытаться скомпилировать скрипт ts.

Возможно, обновление ваших методов на "getSelectField" и "getNumberField" было бы лучшим вариантом .... но, конечно, есть несколько способов, которыми вы могли бы справиться с этим.

...