Условные данные зависят от универсального типа

#javascript #reactjs #typescript #generics

Вопрос:

В основном я использую компонент, основанный на функциях реакции.

*** Но этот вопрос не имеет ничего общего с конкретной реакцией.

 const Component = <Condition extends boolean>(props: React.PropsWithChildren<Props<Condition>>) => {
 

Реквизит:

 interface Props<Condition extends boolean> {
  condition: Condition;
}
 

В этой функции я создаю переменную для хранения некоторых данных.

   const initialValues: Fields<Condition> = (() => {
    const base = {
      unit: '',
    };

    if (props.condition) {
      return {
        ...base,
        from2: '',
      };
    }

    return base;
  })();
 

Этот Fields тип настроен следующим образом:

 interface Base {
  unit: string;
}
interface Extended extends Base {
  from2: string;
}

export type Fields<Condition extends boolean> = Condition extends true ? Extended : Base;
 

Весь кодекс организован вместе:

 interface Base {
  unit: string;
}
interface Extended extends Base {
  from2: string;
}

export type Fields<Condition extends boolean> = Condition extends true ? Extended : Base;

interface Props<Condition extends boolean> extends PropsFromState {
  condition: Condition;
}

const Component = <Condition extends boolean>(props: React.PropsWithChildren<Props<Condition>>) => {
  const initialValues: IJobFormFields<Condition> = (() => {
    const base = {
      unit: '',
    };

    if (props.condition) { // Check if condition (also Condition type) is true
      return {
        ...base,
        from2: '',
      };
    }

    return base;
  })();
};
 

Проблема в том, что я получаю следующую ошибку:

 Type '{ unit: string; } | { unit: string; from2: string; }' is not assignable to type 'Fields<Condition>'.
  Type '{ unit: string; }' is not assignable to type 'Fields<Condition>'.ts(2322)
 

Ответ №1:

Это текущее ограничение дизайна машинописного текста. Он не может сузить тип условного типа в зависимости от неуказанного параметра универсального типа. И хотя параметр type явно не указан, тип Fields<Condition> непрозрачен для компилятора.

Обычно подобные случаи, когда функция возвращает условный тип в зависимости от параметра универсального типа, являются хорошими кандидатами для перезаписи с перегрузками функций. Но поскольку вы не возвращаете ценность initialValues , я считаю, что вам лучше разделить поколение prop на отдельные ветви:

 const BaseComponent = (props: Base) => null
const ExtendedComponent = (props: Extended) => null

const Component = <T extends boolean>(props: Props<T>) => {
  const base = { unit: '' }

  if (props.condition) {
    return <ExtendedComponent {...base} from2="" />
  }

  return <BaseComponent {...base} />
};
 

ссылка на игровую площадку

Ответ №2:

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

 unit?: string
 

Комментарии:

1. Я не вижу причин для этого. Это будет неверно, так как единица измерения не является необязательной, но зависит от условий.