[英]Typescript generic and React components
I'm attempting to write a universal wrapper component that accepts an as
prop which indicates the element to render and also requires any props that the element being rendered requires.我正在尝试编写一个通用包装器组件,该组件接受一个
as
道具,该道具指示要渲染的元素,并且还需要正在渲染的元素所需的任何道具。 With help from this answer , I have a working example:在这个答案的帮助下,我有一个工作示例:
import React, { ComponentType, ElementType } from "react"
type WrapperProps<P = {}> = {
as: ComponentType<P> | ElementType
} & P
const Wrapper = <P = {}>({ as: Element, ...rest }: WrapperProps<P>) => <Element {...rest} />
const Link = ({ href }: { href: string }) => <a href={href}>Click Me</a>
const Test = () => <Wrapper as={Link} /> // Should error as `href` is missing.
const Test2 = () => <Wrapper as={Link} to='/' /> // Should error as `to` is not a valid prop.
const Test3 = () => <Wrapper as={Link} href='/' /> // Should compile.
I'm unable to wrap my head around why the Wrapper
component requires it's own generic type P
.我无法理解为什么
Wrapper
组件需要它自己的泛型类型P
。 In other words, why this wouldn't work:换句话说,为什么这不起作用:
const Wrapper = ({ as: Element, ...rest }: WrapperProps) => <Element {...rest} />
The type WrapperProps
already defines P
as a generic which defaults to an object. WrapperProps
类型已经将P
定义为泛型,默认为 object。 Why must I redefine that when typing Wrapper
?为什么在输入
Wrapper
时必须重新定义它? Is React/TS somehow passing a value for this variable automatically when I call Wrapper
and if not, what extra information does that compiler get from me duplicating the declaration that P
defaults to an empty object?当我调用
Wrapper
时,React/TS 是否以某种方式自动传递了这个变量的值,如果没有,编译器从我那里得到什么额外的信息来复制P
默认为空 object 的声明?
Wrapper
is a function that must take an argument. Wrapper
是一个必须带参数的 function。 The argument is of type WrapperProps
, which is generic.参数是
WrapperProps
类型,它是通用的。
If you didn't make Wrapper
generic, then WrapperProps
would either need to declare its generic type explicitly or else it would fall back to its default:如果你没有使
Wrapper
泛型,那么WrapperProps
要么需要显式声明其泛型类型,否则它将回退到其默认值:
// WrapperProps is implicitly WrapperProps<{}>
const Wrapper = ({ as: Element, ...rest }: WrapperProps) => <Element {...rest} />
const Wrapper = ({ as: Element, ...rest }: WrapperProps<Link>) => <Element {...rest} />
In this sense, it's no different than a chain of two function, where you want to pass a value to the first so that it can pass it to the second:从这个意义上说,它与两个 function 的链没有什么不同,您希望将一个值传递给第一个,以便它可以将其传递给第二个:
function foo(p = {}) { return p; }
function bar(p = {}) { return foo(p); }
bar({ baz: "value" }); // returns { baz: "value" }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.