ts:'Props'可以用与另一种类型无关的任意类型实例化 [英] ts: 'Props' could be instantiated with an arbitrary type which could be unrelated to another type

查看:63
本文介绍了ts:'Props'可以用与另一种类型无关的任意类型实例化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆