Typescript 多态组件打字不起作用

问题描述 投票:0回答:1

我正在尝试创建一个多态组件,但我不明白抛出的错误。希望得到一些帮助,也许还有改进的版本。

预期的结果是我应该能够通过

as
道具。例如

<Text as="button" onClick={e => {}}>
    Hello World
</Text> 
// <button onClick={...}>Hello World</button>

<Text as="div" onClick={e => {}}>
    Hello World
</Text>
// <div onClick={...}>Hello World</div>

打字稿游乐场

我忘了提及,组件在将其传递给 Framer 运动时应正确推断类型

import { motion } from 'framer-motion'

...

const Body = motion(Text)

<Body as={} /> // should infer the types
typescript polymorphism typescript-typings react-typescript framer-motion
1个回答
0
投票

您收到的错误是这样的:

Type 'ForwardRefExoticComponent<Omit<TextProps<ElementType<any>>, "ref"> & RefAttributes<unknown>>' is not assignable to type 'TextComponent'.
  Type 'ReactNode' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | undefined'.
    Type 'null' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | undefined'.

中间的线很突出:

Type 'ReactNode' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | undefined'.

您的

TextComponent
被输入为返回
React.ReactElement
,但通常您会期望组件返回
React.ReactNode
类型。

如果你改变一切都会正常。

type TextComponent = <C extends React.ElementType = "span">(
  props: TextProps<C>
) => React.ReactNode | undefined;

看游乐场


ReactNode
包括
ReactElement
并定义为:

type ReactNode = string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | React.PromiseLikeOfReactNode | null | undefined

因此您会收到此错误,因为

forwardRef
返回的类型无法分配给更窄的
ReactElement
。例如,它可以返回
null
,这是完全有效的,但与
ReactElement
类型不匹配。

© www.soinside.com 2019 - 2024. All rights reserved.