我正在尝试创建一个多态组件,但我不明白抛出的错误。希望得到一些帮助,也许还有改进的版本。
预期的结果是我应该能够通过
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
您收到的错误是这样的:
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
类型不匹配。