Typescript 多态组件类型不起作用

Typescript Polymorphic component typing not working

提问人:nas.engineer 提问时间:11/6/2023 最后编辑:nas.engineer 更新时间:11/6/2023 访问量:29

问:

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

预期的结果是我应该能够通过道具。例如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 motion 时,组件应该正确推断类型

import { motion } from 'framer-motion'

...

const Body = motion(Text)

<Body as={} /> // should infer the types
TypeScript 多态性 React-TypeScript framer-motion

评论


答:

0赞 Alex Wayne 11/6/2023 #1

您收到的错误是这样的:

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'.

你的类型化为返回 ,但通常你希望组件返回该类型。TextComponentReact.ReactElementReact.ReactNode

如果你改变它,一切都会起作用。

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

查看 Playground


ReactNode包括并定义为:ReactElement

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

因此,您收到此错误是因为返回的类型无法分配给更窄的 。例如,它可以返回完全有效但与类型不匹配的 。forwardRefReactElementnullReactElement

评论

0赞 nas.engineer 11/6/2023
谢谢。这确实是正确的。我对 ReactNode 和 ReactElement 感到困惑。但是,通过上述更改,在尝试呈现组件时不会推断类型。没有道具出现。我相信因为把它传给?motion()