我试图输入一个 Package 器组件,它接受一个title
prop和一个children
prop,这是一个函数。传递给 Package 器的所有其他prop都应该在呈现子对象时用作参数:
import React, { ReactNode, InputHTMLAttributes } from "react"
type WrapperProps<P extends object> = {
title: string
children: (props: P) => ReactNode
} & P
const Wrapper = <P extends object>({ title, children, ...rest }: WrapperProps<P>) => {
return children(rest)
}
type InputProps = { type: string, name: string }
const WrappedInput = (inputProps: InputProps) => <Wrapper
title="Hello, World"
{...inputProps}
>{(props) => <input {...props} />}
</Wrapper>
我不明白两件事:
1.在Wrapper
组件中,当调用children(rest)
时,编译器指示参数可分配给类型为“P”的约束,但“P”可以用约束“object”的不同子类型示例化。P
可以示例化什么,这将是不兼容的?我可以强制转换rest as P
,但我想知道问题是什么。
1.在WrappedInput
组件中,编译器认为props
对象(在children render函数中)具有children
和title
属性。当我明确地说调用children
的参数是P
类型,而P
没有这些属性时,怎么会这样呢?
1条答案
按热度按时间fkvaft9z1#
这里的主要问题是,正如你在第二个问题中提到的,传递给render函数的props是
P
类型,但是作为泛型,P被用来捕获所有的props,而不管它们是如何被拆分和使用的。所以对于你的第一个问题,如果你考虑一种情况,你想传递给
children
的props也包含一个title字段,并且类型不一定是字符串,那么类型是不相关的。对于你的第二个问题,这也涉及到第一个问题,最快的方法,同时改变最少的当前结构是指定类型的儿童参数为
省略<P,“标题”|“孩子们”,正如你在这里看到的。 这并不完全像您指定的那样,泛型
P仍然具有
children和
title属性。你可以尝试说
P扩展了一些东西,不允许像
P extends Omit<Record<string,unknown>, "title"|"children"这样的东西尝试满足这个条件,但相当肯定的是,这在 typescript 中不起作用,你不能指定扩展一些记录否定某些字段,链接到[https://github.com/microsoft/TypeScript/issues/31153](https://github.com/microsoft/TypeScript/issues/31153)。 但是不要认为这是一个大问题,如果
P`拥有所有的属性也没关系,您可以从子渲染参数中省略它们。您可能还想将
object
更改为类似Record<string,unknown>
的东西,因为object将接受数组之类的东西,Record通常更适合用于props。你也可以改变你的类型,这样
P
就可以完全是子对象的props,但是你不能把它们扩展到主props类型上。就像这样那么类型就没有不确定性了,因为
P
只用作子函数的参数,并用作WrapperProps
上自己的字段。希望有帮助