简体   繁体   English

React Typescript 儿童道具在类型道具中定义,但不知何故未拾取

[英]React Typescript children prop is defined in type props but somehow not picked up

I'm building a component library using React, TypeScript, Styled Components, and Rollup.我正在使用 React、TypeScript、Styled Components 和 Rollup 构建一个组件库。 Now I've created a Button component using a type interface.现在,我使用类型接口创建了一个 Button 组件。 I then roll up the library to install it locally in my test project.然后,我将库卷起来以在我的测试项目中本地安装它。 I then import the Button and try to use it.然后我导入 Button 并尝试使用它。 I have defined two props for the button: children and type.我为按钮定义了两个属性:children 和 type。 Children is of type React.ReactNode, and type is of type String. Children 是 React.ReactNode 类型,type 是 String 类型。 Now when I use the Button component in my test project is keeps saying the following:现在,当我在我的测试项目中使用 Button 组件时,它一直在说以下内容:

Type '{ children: string;输入'{孩子:字符串; type: string;类型:字符串; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. }' 不可分配给类型 'IntrinsicAttributes & ButtonProps'。 Property 'children' does not exist on type 'IntrinsicAttributes & ButtonProps'.类型“IntrinsicAttributes & ButtonProps”上不存在属性“children”。

Below is my type interface for the Button:下面是我的 Button 类型界面:

import React from "react";

export type ButtonProps = {
  type: String;
  children: React.ReactNode;
};

And below if my Button:如果我的按钮在下面:

import React from "react";
import { ButtonBase } from "./button.style";
import { ButtonProps } from "./button.types";

function getButton(type: String) {
  switch (type) {
    case "base":
      return ButtonBase;
    default:
      return ButtonBase;
  }
}

const Button = ({ type, children }: ButtonProps) => {
  const Component = getButton(type);
  return <Component>{children}</Component>;
};

export default Button;

And this is how I then use the Button in my test project:这就是我在测试项目中使用 Button 的方式:

import { Button } from "aab-react-emerald";

function App() {
  return (
    <div className="App">
      <header className="App-header"></header>
      <Button type="base">Button</Button>
    </div>
  );
}

This is my ButtonBase.这是我的 ButtonBase。 It is a Styled Component which inherits some styling from a basic Button component.它是一个 Styled 组件,它继承了基本 Button 组件的一些样式。 There will be two more buttons, which both will inherit some default styling.还有两个按钮,它们都将继承一些默认样式。

import styled from "styled-components";
import theme from "@theme";

const Button = styled.button`
  display: flex;
  justify-content: center;
  align-items: center;
  border: none;
  padding: 8px 16px;
  height: 40px;
  box-shadow: none;
  font-size: 16px;
  line-height: 24px;
  border-radius: 2px;
  cursor: pointer;
  transition: background-color ${theme.transition};
  transition: ${theme.transition};
`;

export const ButtonBase = styled(Button)`
  color: white;
  background-color: ${theme.colors.g300};

  :hover {
    background-color: ${theme.colors.g200};
  }

  :active {
    background-color: ${theme.colors.g400};
  }
`;

Does anyone know what I should do differently?有谁知道我应该做些什么不同的?

In this code here在此代码中

<Button type="base">Button</Button>

'children' is in fact a string, not a ReactNode - that's why it's getting rejected, the types don't match. 'children' 实际上是一个字符串,而不是 ReactNode - 这就是它被拒绝的原因,类型不匹配。 If you allow a string in your type definition that should fix it:如果您在类型定义中允许一个应该修复它的字符串:

children: React.ReactNode | string;

You can define the component with the React.FC type, which adds the children prop to the props .您可以使用React.FC类型定义组件,这会将children属性添加到props中。 For example:例如:

import React from "react";
import { ButtonBase } from "./button.style";
import { ButtonProps } from "./button.types";

function getButton(type: String) {
  switch (type) {
    case "base":
      return ButtonBase;
    default:
      return ButtonBase;
  }
}

// Using FC there's no need to add the children props into ButtonProps
// as it is already defined in the FC.
const Button: React.FC<ButtonProps> = ({ type, children }) => {
  const Component = getButton(type);

  return <Component>{children}</Component>;
};

export default Button;

Here you have an interesting explanation about the React.FC type!这里有一个关于React.FC类型的有趣解释

I've seen a comment where children should be defined as children: React.ReactNode | string;我看过一条评论,其中孩子应该被定义为children: React.ReactNode | string; children: React.ReactNode | string; But this should not be used as ReactNode also include type of string as an argument and is also a bad practice.但这不应该用作 ReactNode 还包括字符串类型作为参数,这也是一种不好的做法。

Additionally these types are inferred by the HTML Element of Button.此外,这些类型由按钮的 HTML 元素推断。 So they do not need to be specified.所以不需要指定它们。

export type ButtonProps = {
  type: String;
  children: React.ReactNode;
};

Another way of writing your styled button component that you may want to explore could be of另一种编写您可能想要探索的样式按钮组件的方法可能是

const Button = styled.button<
  React.ComponentProps<'button'> & React.HTMLAttributes<HTMLButtonElement>
>`
 display: flex;
  justify-content: center;
  align-items: center;
  border: none;
  padding: 8px 16px;
  height: 40px;
  box-shadow: none;
  font-size: 16px;
  line-height: 24px;
  border-radius: 2px;
  cursor: pointer;
  transition: background-color ${theme.transition};
  transition: ${theme.transition};
`;

You're implementation appears correct.您的实施似乎是正确的。 Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM