简体   繁体   English

Typescript 通用和 React 组件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM