ts:'Props'可以用与另一种类型无关的任意类型实例化 [英] ts: 'Props' could be instantiated with an arbitrary type which could be unrelated to another type
问题描述
const withFirebase = <Props extends {firebase: Firebase}>(
Component: React.ComponentType<Props>
): ComponentType<Omit<Props, "firebase">> => (props) => (
<FirebaseContext.Consumer>
{(firebase) => <Component {...props} firebase={firebase} />}
</FirebaseContext.Consumer>
);
export default withFirebase;
这里
<Component {...props} firebase={firebase} />
引发以下打字稿错误
Type 'Pick<Props, Exclude<keyof Props, "firebase">> & { firebase: Firebase | null; children?: ReactNode; }' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Type 'Pick<Props, Exclude<keyof Props, "firebase">> & { firebase: Firebase | null; children?: ReactNode; }' is not assignable to type 'Props'.
'Props' could be instantiated with an arbitrary type which could be unrelated to 'Pick<Props, Exclude<keyof Props, "firebase">> & { firebase: Firebase | null; children?: ReactNode; }
省略道具,火力"".已添加,以避免在包装的组件"导入中出现必需的prop错误.
Omit<Props, "firebase"> is added to avoid the required prop error in the Wrapped component import.
喜欢
const App = () => {
return (
<ItemWithFirebase /> // If not omit is available this will throw prop firebase not available error
)
}
const Item: FC<{firebase: Firebase}> = ({firebase}) => {
...
}
const ItemWithFirebase = withFirebase(Item);
我按如下方式撒播了传播道具
I have casted the spread props as below
<Component {...(props as Props)} firebase={firebase} />}
但是我不确定我是否做对了.您能否让我知道是否还有其他方法可以解决此错误?
But I am not sure if I am doing it right. Could you please let me know if there are any other way to tackle this error?
推荐答案
编写HOC时总是出现这种情况.您正在查看错误,它显示我们采用 Props
,我们删除了 Props ['firebase']
,我们添加了 {firebase:Firebase |null}
,我们不确定该对象是否可分配给 Props
'".您可能会想,如果我删除了 firebase
,然后又将其添加回去,那当然也是一样".从技术上讲,道具扩展了{firebase:Firebase}
,这意味着 Props ['firebase']
可能比 Firebase 更为具体.代码>,在这种情况下,您提供给它的值是不够的.这种奇怪的边缘情况是您收到错误的两个原因之一.
This comes up all the time when writing HOCs. You're looking at the error and it says "We take Props
, we remove Props['firebase']
, we add {firebase: Firebase | null}
, and we're not sure if this object is assignable to Props
". You might think, "if I removed firebase
and then added it back, of course that's the same thing". Technically, Props extends {firebase: Firebase}
means that Props['firebase']
could be something more specific than Firebase
, in which case the value that you provide to it wouldn't be sufficient. That weird edge case is one of two reasons that you get an error.
另一个原因是, Props
不允许 firebase
为 null
,而允许 Consumer
说它可能具有 Firebase
或 null
.
The other reason is that Props
doesn't allow for firebase
to be null
, but the Consumer
says that it could either have Firebase
or null
.
但是99.9%的时间是同一件事,因此可以像在此所做的那样断言 {...(props as Props)}
.您可能想扩展 Props
以允许 null
,但是如果您知道应用程序中它不会是 null
,那么这不是问题
But 99.9% of the time it is the same thing, so it's fine to assert {...(props as Props)}
like you have done here. You might want to expand Props
to allow null
, but if you know that it's not going to be null
in your app then it's not an issue.
如果让通用的 Props
代表没有 firebase
的道具,则可以避免某些错误.我们没有从返回中删除 firebase
,而是将其添加到 Component
.我们忽略
来自 Props
的 firebase
的任何现有定义,从而排除了 Component
需要某些值的情况 firebase
除外.
You can avoid some of the errors if you let your generic Props
represent the props without firebase
. Instead of dropping firebase
from the return, we add it to the Component
. We Omit
any existing definition of firebase
from Props
which rules out the edge case where the Component
requires some value of firebase
other than what we provide.
const withFirebase = <Props extends {}>(
Component: React.ComponentType<Omit<Props, 'firebase'> & {firebase: Firebase | null}>
): ComponentType<Props> => (props) => (
<FirebaseContext.Consumer>
{(firebase) => <Component {...props} firebase={firebase} />}
</FirebaseContext.Consumer>
);
这篇关于ts:'Props'可以用与另一种类型无关的任意类型实例化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!