Есть необычный вопрос об исключении реквизита в HoC
У меня есть компонент реакции:
interface IMyComponentProps {
prop1: string,
prop2: Function,
items1: string[],
items2: string[],
}
и у меня есть HOC, который берет этот компонент и передает ему элементы1 и элементы2
interface IWithItems {
items1: string[],
items2: string[],
}
type WithoutItems<T extends IWithItems> = Omit<T, 'items1'|'items2'>;
function HoC<T extends IWithItems>(
WrappedComponent:
React.ComponentClass<T>
| React.FunctionComponent<T>,
): React.ComponentClass<WithoutItems<T>> {
class WithItemsWrapper extends React.Component<WithoutItems<T>, IWithItems> {
state = {
items1: [],
items2: [],
};
async componentDidMount() {
const items1 = await this.getItems1();
const items2 = await this.getItems2();
this.setState({
items1,
items2,
});
}
getItems1 = () => (
// from backend
);
getItems2 = () => (
// from backend
);
render() {
return (
<WrappedComponent
{...this.props}
items1 = {this.state.items1}
items2 = {this.state.items2}
/>
);
}
}
return hoistNonReactStatics(WithItemsWrapper, WrappedComponent);
}
Обернутый компонент имеет собственные реквизиты, и эти реквизиты содержат элементы1, элементы2. HoC извлекает элементы из бэкэнда и передает их обернутому компоненту
в моем файле index.ts я экспортирую его как
export default HoC(MyComponent);
идея в том, что после этого экспорта и импорта этого в другой файл MyComponent должны требоваться prop1 и prop2, но не items1 и items2, потому что они уже прошли в HoC.
Но теперь он говорит
Error:(59, 12) TS2322: Type 'Readonly<Pick<T, Exclude<keyof T, "items1" | "items2">>> & { items1: never[]; items2: never[]; children?: ReactNode; }' is not assignable to type 'IntrinsicAttributes & T & { children?: ReactNode; }'.
Type 'Readonly<Pick<T, Exclude<keyof T, "items1" | "items2">>> & { items1: never[]; items2: never[]; children?: ReactNode; }' is not assignable to type 'T'.
Возможно ли это, и если да, то что я делаю не так?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы поступили наоборот. HoC принимает компонент с items1 и items2 и возвращает HOC без items1 и items2. Итак, для компонента
let ResultingComponent = HoC(MyComponent);
вы должны предоставить только prop1 и prop2. items1 и items2 будут заполнены из HoC.
Если вы хотите передать компонент без items1 и items2, но получившийся компонент содержит items1 и items2, вы должны сделать так:
function HoC<T>(
WrappedComponent:
React.ComponentClass<T>
| React.FunctionComponent<T>,
): React.ComponentClass<T & IWithItems> {
class WithItemsWrapper extends React.Component<T & IWithItems, IWithItems> {
render() {
return (
<>
// Do some rendering based on this.props.items1 and this.props.items2
<div>{this.props.items1.map(e => (<div>{e}</div>))}</div>
<WrappedComponent
{...this.props}
/>
</>
);
}
}
return hoistNonReactStatics(WithItemsWrapper, WrappedComponent);
}
Но обратите внимание, что в этом случае item1 и item2 должны быть предоставлены результирующему компоненту из HoC. Внутри HoC вы не должны получать эти пропсы от бэкенда, но вы должны рендерить что-то на основе этих пропсов и не передавать их в WrappedComponent.
кажется я нашел решение
Прежде всего упростите WithoutItems и измените определение HOC.
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
type Diff<T, K> = Omit<T, keyof K>;
type WithoutItems<T> = Diff<T, IWithItems>;
function HoC<P>(
WrappedComponent:
React.ComponentClass<P>
| React.FunctionComponent<P>,
): React.ComponentClass<WithoutItems<P>> {
class WithItemsWrapper extends React.Component<WithoutItems<P>, IWithItems> {
и следующее, что нужно сделать, это сделать карту реквизита явно типом P
// HoC render method
render() {
return (
<WrappedComponent
{...this.props as P}
items1 = {this.state.items1}
items2 = {this.state.items2}
/>
);
}
все остальное остается как было.
решение найдено здесь
спасибо за ваш ответ, но я думаю, что это не совсем то, что я ищу. Компонент должен ожидать элементы 1 и элементы 2 на основе его интерфейса. Но я пытаюсь разделить выборку данных из бэкэнда в HOC, чтобы упростить тестирование компонента. идея в том, что я могу импортировать компонент и передавать эти два реквизита из любого места, но если я не хочу этого делать, я могу импортировать компонент, обернутый этим HOC, и заставить его работать сам по себе. цель - реквизиты items1 и items2 должны существовать в компоненте, но когда он обернут HOC, их не должно быть, потому что они перешли из HOC. Может я плохо мыслю?