Интерфейс расширения машинописного текста не позволяет перезаписывать свойство

Typescript, по-видимому, не позволяет мне перезаписывать свойство, которое не требуется. У меня есть пара интерфейсов:

interface IField {

  label:                string;
  model:                string;
  placeholder?:         string;
  addon?:               string;
  showOn?:              IDictionary <string | number>;
  maxlength?:           number;

}
interface ICheckboxField extends IField {

  model?:               string;
  type:                 'checkbox';
  default?:             string;
  options:              IOption[];
  validation?:    {
    required?:          string;
  };
}

Поэтому в ICheckboxField я установил, что свойство модели не требуется. Все остальные поля, расширяющие IField, должны иметь требуемую модель.

Является ли это ограничением в Typescript или есть решение, отличное от расширения интерфейса и просто добавления свойств специально для интерфейса?


person Mattijs    schedule 03.03.2017    source источник
comment
Вы не можете изменить тип или модификаторы существующих свойств при расширении (или объединении)   -  person Nitzan Tomer    schedule 03.03.2017


Ответы (2)


Что вы можете сделать, так это поместить общие свойства IField и ICheckboxField в общий интерфейс:

interface IBase {
    label: string;
    placeholder?: string;
    addon?: string;
    showOn?: IDictionary;
    maxlength?: number;
}

interface IField extends IBase {
    model: string;
}

interface ICheckboxField extends IBase {
    model?: string;
    type: 'checkbox';
    default?: string;
    options: IOption[];
    validation?: {
        required?: string;
    };
}

Другой вариант — разделить IField на два интерфейса:

interface IField {
    label: string;
    placeholder?: string;
    addon?: string;
    showOn?: IDictionary;
    maxlength?: number;
}

interface IFieldOptionalModel extends IField {
    model?: string;
}

interface IFieldMandatoryModel extends IField {
    model: string;
}

interface ICheckboxField extends IFieldOptionalModel {
    type: 'checkbox';
    default?: string;
    options: IOption[];
    validation?: {
        required?: string;
    };
}
person Nitzan Tomer    schedule 03.03.2017
comment
Я смотрю ваше второе предложение с необязательным и обязательным интерфейсом. Это может быть фактически повторно использовано в будущем, поэтому я пойду с этим. - person Mattijs; 05.03.2017

Вы пытаетесь переопределить строгий тип (IField), где свойство является обязательным, более свободным типом (ICheckboxField), где оно стало обязательным.

Компилятор не одобряет это, но возможно и обратное:

interface Loose {
  label:string;
  model?:string;
}

interface Strict extends Loose {
  model:string;
}

var a:Loose = {
  label:"bar",
}

var b:Strict = {
  label: "baz",
  model: "me"
}

Таким образом, вы можете добавить еще один интерфейс поверх обоих, где поле модели определено как необязательное, а затем переопределить его как обязательное в IField.

Другим вариантом может быть использование keyof и добавленных типов поиска

person alebianco    schedule 03.03.2017
comment
Спасибо за Ваш ответ. Я думаю, что другой ответ будет работать немного лучше для меня. Ваше здоровье - person Mattijs; 05.03.2017