ค้นหาเว็บไซต์

reactjs - React typescript การพิมพ์คอมโพเนนต์ React แบบ General ด้วยพารามิเตอร์ที่เหลือ


ฉันกำลังสร้างแอป React ด้วย TypeScript ฉันมีคอมโพเนนต์หุ้ม ConnectedComponent สำหรับการทำงานกับการแบ่งหน้า ซึ่งรับคุณสมบัติ container เป็นอินพุต ซึ่งเป็นคอมโพเนนต์ React ฉันพยายามที่จะให้เกิดการอ้างอิงชนิดของคุณสมบัติของคอมโพเนนต์ container เมื่อใช้คอมโพเนนต์หุ้ม นอกจากนี้ยังมีพารามิเตอร์การแบ่งหน้า CommonContainerProps ที่ถูกส่งมาจากคอมโพเนนต์หุ้มเอง ดังนั้นจะต้องไม่รวมอยู่ในชนิดที่ส่งผ่าน

type CommonContainerProps = {
  ref?: any;
  itemCount: number;
  onItemsRendered?: (indexes: any) => void;
  width: number;
  height: number;
};

type OmitCommonProps<T extends CommonContainerProps> = Omit<
  T,
  keyof CommonContainerProps
>;

type CommonComponentProps<TContainerProps extends CommonContainerProps> = {
  path: string;
  container: ComponentType<TContainerProps>;
  containerRef?: (value: any) => void;
};

type ComponentProps<
  TContainerProps extends CommonContainerProps
> = OmitCommonProps<TContainerProps> & CommonComponentProps<TContainerProps>;

type ConnectProps = {
  pagination: any;
};

type ConnectedComponentProps<
  TContainerProps extends CommonContainerProps
> = ConnectProps & ComponentProps<TContainerProps>;

export class ConnectedComponent<
  TContainerProps extends CommonContainerProps
> extends React.PureComponent<ConnectedComponentProps<TContainerProps>> {
  render() {
    const {
      path,
      pagination,
      container,
      containerRef,
      ...containerProps
    } = this.props;

    const Container = this.props.container as ComponentType<TContainerProps>;

    return (
      <Container
        {...containerProps}
        // props collect in current ConnectedComponent
        ref={containerRef}
        itemCount={10}
        onItemsRendered={console.log}
        width={100}
        height={100}
      />
    );
  }
}

ตัวอย่างการใช้งาน:

type TestComponentType = {
  width: number;
  height: number;
  itemCount: number;
  onItemsRendered?: (value: any) => void;
  className: string;
};

const TestComponent: FC<TestComponentType> = ({
  width,
  height,
  itemCount,
  onItemsRendered,
  className
}) => (
  <div>
    <div>width: {width}</div>
    <div>height: {height}</div>
    <div>itemCount: {itemCount}</div>
    <div>className: {className}</div>
  </div>
);

export default function App() {
  return (
    <div className="App">
      <ConnectedComponent
        container={TestComponent}
        path="test"
        pagination="testPagination"
        className="className"
      />
    </div>
  );
}

แซนด์บ็อกซ์โค้ด

เมื่อประกอบคอมโพเนนต์ Container จะเกิดข้อผิดพลาด

    Type 'Pick<Readonly<ConnectedComponentProps<TContainerProps>> & Readonly<{ children?: ReactNode; }>, "children" | Exclude<...>> & { ...; }' is not assignable to type 'IntrinsicAttributes & TContainerProps & { children?: ReactNode; }'.
      Type 'Pick<Readonly<ConnectedComponentProps<TContainerProps>> & Readonly<{ children?: ReactNode; }>, "children" | Exclude<...>> & { ...; }' is not assignable to type 'TContainerProps'.
        'Pick<Readonly<ConnectedComponentProps<TContainerProps>> & Readonly<{ children?: ReactNode; }>, "children" | Exclude<...>> & { ...; }' is assignable to the constraint of type 'TContainerProps', but 'TContainerProps' could be instantiated with a different subtype of constraint 'CommonContainerProps'.ts(2322)

คุณช่วยบอกฉันได้ไหมว่าจะประกาศคอมโพเนนต์นี้อย่างไรเพื่อให้การพิมพ์ทำงานได้ดี