Как написать TypeScript интерфейс реквизита, содержащий объект, и объединить его с defaultProps

У меня есть интерфейс реквизита TypeScript, например:

interface Props {
  children: ReactNode;
  components?: object;
  mode: string;
  actions: {
    copy: boolean;
    code: boolean;
    refresh: boolean;
    source: boolean;
  };
  source?: string;
  readonly withStyles?: object;
  styles?: object;
}

И у меня есть соответствующий интерфейс defaultProps как таковой:

class Box extends Component<Props, State> {
  public static defaultProps = {
    mode: 'full',
    actions: {
      copy: true,
      code: true,
      refresh: true,
      source: true,
    },
  };

  ....

}

Пользователь должен иметь возможность указать только частичный набор actions для компонента, а остальные должны быть объединены из defaultProps.

Например, если пользователь указывает:

<Box actions = {{ copy: false }} />

Я ожидаю, что defaultProps заполнит пробел, чтобы создать props.actions как { copy: false, code: true, refresh: true, source: true }.

Однако в настоящее время я получаю ошибку TypeScript: Type '{ copy: boolean; }' is missing the following properties from type '{ copy: boolean; code: boolean; refresh: boolean; source: boolean; }': code, refresh, source.

Как я могу заставить это работать правильно?

TypeScript v.3.2.2
@types/react v16.8.2

TypeScript 3.0, по-видимому, решил проблему нечтения из defaultProps, но я не могу найти пример, в котором есть объект в реквизитах. Примеры слишком упрощены. devblogs.microsoft.com/typescript/announcing-typescript-3-0/‌​…

sidewalksalsa 26.02.2019 08:18

Примечание. Я знаю, что могу объединить defaultProps с реквизитом. Это будет полностью работать, но это не имеет смысла на самом деле делать. TypeScript должен делать это за меня. Может это баг?

sidewalksalsa 26.02.2019 09:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
6
2
433
1

Ответы 1

В React нет глубокой проверки/слияния defaultProps, и TypeScript этого не изменит.

Одним из способов решения этой проблемы является создание компонента-оболочки:

//pure js

const defaultActions = {
  copy: true,
  paste: false
};

const Box = props => JSON.stringify(props);
const BoxWithDefaultActions = ({ actions, ...rest }) => (
  <Box actions = {{ ...defaultActions, ...actions }} {...rest} />
);

const App = () => (
  <>
      <Box actions = {{ copy: false }} />
      <BoxWithDefaultActions actions = {{ copy: false }} />
  </>
);

/**
Box:
  { "actions": { "copy": false } }
Box with actions:
  { "actions": { "copy": false, "paste": false } }
**/

//HOC or render props component could be even better "solution". 

Подробнее об этом можно прочитать в Реагировать на проблему Github: https://github.com/facebook/реагировать/issues/2568

Другие вопросы по теме