类型中缺少属性“孩子”

Posted

技术标签:

【中文标题】类型中缺少属性“孩子”【英文标题】:Property 'children' is missing in type 【发布时间】:2020-07-05 12:25:42 【问题描述】:

我正在尝试使用 babel-loader 和 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;

这里有什么我做错了吗?

【问题讨论】:

能否请您也粘贴Collapsible 的实现。 @ShaunLuttin 嗨,肖恩,我已经编辑了我的问题 :) 在没有工作沙箱的情况下调试有点麻烦,但是您是否尝试过不明确定义children?例如。通过使用 codesandbox.io/s/intelligent-http-rj108 中的 React.FC 中的默认机制?对于您的情况,这将意味着以下更改: edit const Collapsible: React.FC&lt;Props&gt; = ( children, title, ...rest ) =&gt; remove children: ReactNode; from type definition 嗨@Gustav,您能否将其发布为答案,这样您就可以获得赏金,因为您首先通过可行的解决方案帮助我解决了这个问题?这不是我使用的解决方案,因为我想将children 专门声明给需要它们的功能组件。但既然它起作用了,我希望你能得到赏金:) @Erazihel 完成! :-) 【参考方案1】:

步骤 1

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

你的代码应该是这样的:

const Collapsible : React.FC&lt;Props&gt; = ( children, title, ...rest ) =&gt;

第二步

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

【讨论】:

【参考方案2】:

我添加了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;
  
;

【讨论】:

【参考方案3】:

一种可能的解决方案是利用函数组件中的默认子机制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

【讨论】:

以上是关于类型中缺少属性“孩子”的主要内容,如果未能解决你的问题,请参考以下文章

打字稿样式组件错误:“类型'孩子:字符串;'与类型'IntrinsicAttributes'没有共同的属性。”

d3.json:“未捕获的类型错误:无法读取未定义的属性‘孩子’”

Swift Firebase 快照查询缺少孩子

为孩子提供属性时如何为 React.cloneElement 分配正确的类型?

在Django模板中循环相关模型的孩子

缺少孩子将 inspect.exe 与 UIAComWrapper.dll 进行比较返回 AE.RootElement.FindAll(TreeScope.Children, Condition.Tr