【问题标题】:Type 'string' is not assignable to type 'undefined'. TS2769类型“字符串”不可分配给类型“未定义”。 TS2769
【发布时间】:2021-09-14 11:15:55
【问题描述】:

我根据href 类型添加了一些条件样式。出于某种原因,如果我将 as 添加到 Button styled-component 我会收到 TS 错误:Type 'string' is not assignable to type 'undefined'. TS2769

组件

interface LinkProps {
  to: string;
  target?: string;
  as?: string;
  className?: string;
  children: ReactChildren | React.ReactNode | string;
}

const Button = styled(RLink)`
  text-decoration: none;
`;

export const Link = ({
  to,
  target,
  children,
  as = 'a',
  className
}: LinkProps) => {
  return (
    <Button
      as={as}
      to={to}
      target={target}
      rel="noopener"
      className={className}
    >
      {children}
    </Button>
  );
};

没有as:

没有as:

完整的 TS 错误

index.js:1 /frontend/claim-handler/src/components/shared/Link/index.tsx
TypeScript error in /frontend/claim-handler/src/components/shared/Link/index.tsx(39,6):
This JSX tag's 'children' prop expects type 'never' which requires multiple children, but only a single child was provided.  TS2745

37 | }: LinkProps) => {
  38 |   return (
    > 39 |     <Button
           |      ^
40 |       as={as}
        41 |       to={to}
        42 |       target={target}
console.<computed> @ index.js:1
handleErrors @ webpackHotDevClient.js:174
push.../../node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage @ webpackHotDevClient.js:213


index.js:1 /frontend/claim-handler/src/components/shared/Link/index.tsx
TypeScript error in /frontend/claim-handler/src/components/shared/Link/index.tsx(40,7):
No overload matches this call.
Overload 1 of 2, '(props: Omit<Omit<import("/node_modules/@types/react-router-dom/index").LinkProps<unknown> & RefAttributes<HTMLAnchorElement> & LinkProps, never> & Partial<...>, "theme"> & { ...; } & { ...; }): ReactElement<...>', gave the following error.
  Type 'string' is not assignable to type 'undefined'.  TS2769

  38 |   return (
    39 |     <Button
    > 40 |       as={as}
      |       ^
      41 |       to={to}
      42 |       target={target}
      43 |       rel="noopener"

编辑

通过删除我不同意的选项 as,这些类型不是组件期望作为 Props 接收的,而不仅仅是参数吗?

以下是新错误:

【问题讨论】:

  • 您将as 标记为可选,视为您将a 设为默认值,只需选择as 的可选? 即可
  • 你试过用“forwardedAs”代替“as”吗? github.com/styled-components/styled-components/issues/…
  • 谢谢大家,查看更新的问题
  • 感谢 forwardedAs 的建议,这也会引发同样的错误

标签: javascript reactjs typescript styled-components


【解决方案1】:

主要问题是您试图将极宽的类型 string 传递给 prop 接受相当大但仍精确定义的字符串集作为本机 html tags 的名称。 如果你打算只传递as 属性作为html 标签的名称(即不是其他功能或类组件),你可以像这样输入as

interface LinkProps {
  to: string;
  target?: string;
  as?: keyof JSX.IntrinsicElements;
  className?: string;
  children: ReactChildren | React.ReactNode | string;
}

这应该可以解决您的问题。

还有一个小问题。 虽然自己输入 children 道具是完全可以的。这是相当脆弱的方式。你已经弄错了。 ReactChildren 不是一种反应儿童数组。这是一种React.Children 接口,结合了实用功能以与children 属性一起使用。

对于输入 children,prop react 会暴露特殊的帮助器类型 React.PropsWithChildren。如果你希望你可以以更稳定的方式重写你的代码:

import * as React from 'react'
import styled from 'styled-components'

interface LinkProps {
    to: string;
    target?: string;
    as?: keyof JSX.IntrinsicElements;
    className?: string;
}

const Button = styled(RLink)`
    text-decoration: none;
`;

export const Link = ({
    to,
    target,
    children,
    as = 'a',
    className
}: React.PropsWithChildren<LinkProps>) => {
    return (
        <Button
            as={as}
            to={to}
            target={target}
            rel="noopener"
            className={className}
        >
            {children}
        </Button>
    );
};

【讨论】:

    猜你喜欢
    • 2022-01-07
    • 2021-08-19
    • 2018-07-20
    • 2021-10-19
    • 2018-06-24
    • 1970-01-01
    • 2021-04-06
    • 2019-07-12
    • 2021-09-19
    相关资源
    最近更新 更多