reactjs - React-underkomponenter i Typescript


Vi har noen komplekse sammensetninger av komponenter, og jeg har problemer med å gjøre dem typesikre. Basert på koden nedenfor, ville jeg forventet at Typescript kunne gi typer for Menu.Item eller Menu.Link, men det gjør den ikke av en eller annen grunn, de blir inferert som "any" (som blir raffinert til JSX.Element<any> når du pakker det inn i JSX). Har du noen idé om hvorfor dette skjer?

import * as React from 'react';

type RootFunctionComponent<OwnProps, SubComponents> = React.FunctionComponent<OwnProps> & SubComponents;

interface ItemProps {
    text: string;
};

interface LinkProps {
    href: string;
}

const Item: React.FunctionComponent<ItemProps> = props => <div {...props} />;
const Link: React.FunctionComponent<LinkProps> = props => <div {...props} />;

interface MenuSubComponents {
    Item: React.FunctionComponent<;
    Link: typeof Link;
}

const Menu: React.FunctionComponent<{}, MenuSubComponents> & MenuSubComponents = props => <div {...props} />

Menu.Item = Item;
Menu.Link = Link;


const Test: React.FunctionComponent<{}> = () => {
    return <>
        <Menu>
            <Menu.Item text={false} />
            <Menu.Link />
        </Menu>
    </>
}

Resultat :

Svar #1

Problemet var med menytypenes definisjoner:

React.FC<{}, MenuSubComponents>

Korrekt bruk er:

React.FC<MenuSubComponents>

Du kan se dette i aksjon her: https://codesandbox.io/s/condescending-lamarr-xjkcw

Svar #2

Her er et komplett eksempel på en Higher Order Component-tabell med props

import React from 'react'
import { tw } from 'twind'

import Body from './Body'
import Cell from './Cell'
import Head from './Head'
import Row from './Row'

export type CommonPropsType = {
  className?: string
  children: React.ReactNode
}

type TableSubComponents = {
  Row: typeof Row
  Cell: typeof Cell
  Head: typeof Head
  Body: typeof Body
}

type TablePropsType = CommonPropsType & { wrapperClassName?: string }

const Table: React.FunctionComponent<TablePropsType> & TableSubComponents = (
  props: TablePropsType
) => {
  const { className, children, wrapperClassName } = props
  return (
    <div className={tw('overflow-x-auto pb-2', wrapperClassName)}>
      <table
        className={tw('min-w-full leading-normal', className)}
        cellPadding="8">
        {children}
      </table>
    </div>
  )
}

Table.Row = Row
Table.Cell = Cell
Table.Head = Head
Table.Body = Body

export default Table

Relaterte artikler