Чем больше я думаю об этом вопросе, тем больше мне нравится подход Фрэнка Ли .Я хотел бы сделать две модификации: (1) ввести дополнительный SFC, чтобы избежать приведения, и (2) извлечь внешний тип реквизита из обернутого компонента C
вместо его жесткого кодирования.(Если мы жестко закодируем Props<T>
, TypeScript по крайней мере проверит, что он совместим с this.C
, но мы рискуем потребовать реквизиты, которые this.C
на самом деле не требуют или не могутпринимать необязательные реквизиты, которые this.C
на самом деле принимает.) Потрясающе то, что ссылка на тип свойства из аргумента типа в предложении extends
работает, но, похоже,!
class WrappedBaseFormCard<T> extends React.Component<
// Or `PropsOf<WrappedBaseFormCard<T>["C"]>` from @material-ui/core if you don't mind the dependency.
WrappedBaseFormCard<T>["C"] extends React.ComponentType<infer P> ? P : never,
{}> {
private readonly C = withStyles(styles)(
// JSX.LibraryManagedAttributes handles defaultProps, etc. If you don't
// need that, you can use `BaseFormCard<T>["props"]` or hard-code the props type.
(props: JSX.LibraryManagedAttributes<typeof BaseFormCard, BaseFormCard<T>["props"]>) =>
<BaseFormCard<T> {...props} />);
render() {
return <this.C {...this.props} />;
}
}
Я думаю, что любые жалобызатраты времени выполнения этого подхода, вероятно, бессмысленны в контексте всего приложения React;Я поверю им, когда кто-то представит данные, подтверждающие их.
Обратите внимание, что подход Лукаса Зека с использованием SFC сильно отличается: каждый раз, когда изменяется реквизит внешнего SFC, и он вызывается снова, вызывается withStyles
опять же, генерируя wrapper
, который выглядит как React как новый тип компонента, поэтому React отбрасывает старый экземпляр wrapper
, и создается новый внутренний компонент BaseFormCard
.Это может иметь нежелательное поведение (состояние сброса), не говоря уже о больших накладных расходах во время выполнения.(Я на самом деле не проверял это, поэтому дайте мне знать, если я что-то упустил.)