属性 'children' 类型缺失

Property 'children' is missing in type

我正在尝试使用 babel-loader and ts-loader.

通过 Typescript 设置 Storybook

一切正常,除了在 React 组件中使用 children

[tsl] ERROR in .../stories/index.stories.tsx(8,56)
      TS2769: No overload matches this call.
      Property 'children' is missing in type '{ title: string; }' but required in type 'Props'.

这是 .storybook/main.js 文件:

module.exports = {
  addons: [
    "@storybook/addon-knobs",
  ],
  stories: ["../packages/**/*.stories.tsx"],
  webpackFinal: async config => {
    config.module.rules.push({
      test: /\.(ts|tsx)$/,
      exclude: /node_modules/,
      use: [
        {
          loader: require.resolve('ts-loader')
        },
        {
          loader: require.resolve('babel-loader'),
          options: {
            presets: [
              "@babel/preset-env",
              "@babel/preset-react"
            ]
          }
        }
      ],
    });

    config.resolve.extensions.push('.ts', '.tsx');

    return config;
  }
};

这是 index.stories.tsx 文件:

import React from "react";

import Collapsible from "../src";

export default {
  title: "Collapsible"
};

const content = <span>Content</span>;

export const simpleCollapsible = () => (
  <Collapsible title="Collapsible">{content}</Collapsible>
);

这是 Collapsible 的实现:

import React, { ReactNode, useState } from "react";
import styled, { ThemeProvider } from "styled-components";
import {
  BorderProps,
  ColorProps,
  FlexboxProps,
  LayoutProps,
  SpaceProps,
  TypographyProps
} from "styled-system";
import Theme from "@atw/theme";

import { KeyboardArrowDown } from "@styled-icons/material";

import Box from '~/box';
import Button from '~/button';

interface Props
  extends BorderProps,
    ColorProps,
    FlexboxProps,
    LayoutProps,
    SpaceProps,
    TypographyProps {
  children: ReactNode;
  title: string;
}

const Collapsible = ({ children, title, ...rest }: Props) => {
  const [isCollapsed, setIsCollapsed] = useState(false);

  const handleCollapse = () => {
    setIsCollapsed(!isCollapsed);
  };

  return (
    <ThemeProvider theme={Theme}>
      <Button
        border="none"
        padding={0}
        marginBottom={2}
        width={1}
        textAlign="start"
        onClick={handleCollapse}
        {...rest}
      >
        <IconBox isCollapsed={isCollapsed}>
          <KeyboardArrowDown size="24px" />
        </IconBox>
        {title}
      </Button>
      {!isCollapsed && (
        <Box display="flex" flexDirection="column">
          {children}
        </Box>
      )}
    </ThemeProvider>
  );
};

export default Collapsible;

有什么地方我做错了吗?

第 1 步

添加React.FC:它已经为您声明了children。并在 React 中添加您的自定义道具。

你的代码应该是这样的:

const Collapsible : React.FC<Props> = ({ children, title, ...rest }) => {

第 2 步

interface Props extends BorderProps,
    ColorProps,
    FlexboxProps,
    LayoutProps,
    SpaceProps,
    TypographyProps {
  children: ReactNode; // as React.FC declares it for you, just delete this line
  title: string;
}

我添加了 Babel Preset Typescript,错误消失了。

这是我的 .storybook/main.js 现在的样子:

module.exports = {
  addons: [
    "@storybook/addon-knobs",
  ],
  stories: ["../packages/**/*.stories.tsx"],
  webpackFinal: async config => {
    config.module.rules.push({
      test: /\.(ts|tsx)$/,
      exclude: /node_modules/,
      use: [
        {
          loader: require.resolve('ts-loader'),
          options: {
            configFile: '../tsconfig.json',
            transpileOnly: true
          }
        },
        {
          loader: require.resolve('babel-loader'),
          options: {
            presets: [
              "@babel/preset-env",
              "@babel/preset-react",
              "@babel/preset-typescript"
            ]
          }
        }
      ],
    });

    config.resolve.extensions.push('.ts', '.tsx');

    return config;
  }
};

一种可能的解决方案是利用功能组件中的默认子项机制,React.FC,它允许您安装子项而无需将它们显式包含为类型定义中的道具。对于您的情况,可以通过应用以下更改来实现:

interface Props
  extends BorderProps,
    ColorProps,
    FlexboxProps,
    LayoutProps,
    SpaceProps,
    TypographyProps {
  title: string;
}

const Collapsible: React.FC<Props> = ({ children, title, ...rest }) => {
  ...
};

Working sandbox for this