首页 > 解决方案 > 如何为样式组件的组合制作接口?

问题描述

我正在尝试为样式组件的组合创建一个接口:

import styled from "styled-components"

const Title = styled.div``
const TitleNumber = styled.div``
const TitleNumberDigit = styled.div``
const TitleName: React.ComponentType = styled.div``

interface IUiStepTitleNumber extends React.ComponentType {
    Digit: React.ComponentType
}

interface IUiStepTitle extends React.ComponentType {
    Number: IUiStepTitleNumber
    Name: React.ComponentType
}

const UiStepTitle : IUiStepTitle = Object.assign(Title, {
    Number: Object.assign(TitleNumber, {
        Digit: TitleNumberDigit,
    }),
    Name: TitleName,
})

export default UiStepTitle

对于这个用例:

<UiStepTitle>
    <UiStepTitle.Number>
        <UiStepTitle.Number.Digit>
            {stepNumber}
        </UiStepTitle.Number.Digit>
    </UiStepTitle.Number>

    <UiStepTitle.Name>{stepTitle}</UiStepTitle.Name>
</UiStepTitle>

但我有一个打字稿错误

An interface can only extend an object type or intersection of object types with statically known members

如何正确组合这样的接口?

标签: javascriptreactjstypescriptstyled-components

解决方案


最简单的解决方案是不使用组件作为命名空间。

export const Title = styled.div``
export const TitleNumber = styled.div``
export const TitleNumberDigit = styled.div``
export const TitleName: React.ComponentType = styled.div``

并像使用它一样

import { Title, TitleNumber, TitleNumberDigit, TitleName } from './Title' 

...


<Title>
    <TitleNumber>
        <TitleNumberDigit>
            {stepNumber}
        </TitleNumberDigit>
    </TitleNumber>
    <TitleName>{stepTitle}</TitleName>
</Title>

如果您确实有一个用例希望通过接口提供组件,您可以按如下方式构建您的接口:

interface Title {
  Body: FC<BodyProps>;
  Number: FC<NumberProps>;
 ...
}

const fancyTitle: Title = {
  Body: FancyTitle,
  Number: FancyNumber,
 ...
}

// dummy factory
export const createTitle = (): Title => fancyTitle;

像这样使用它:

import { createTitle } from './Title'

const Title = createTitle();

(
  <Title.Body>
    <Title.Number>
      ...
    </Title.Number>
    ...
  </Title.Body>
);

推荐阅读