【问题标题】:ts: 'Props' could be instantiated with an arbitrary type which could be unrelated to another typets:“道具”可以用与另一种类型无关的任意类型实例化
【发布时间】:2021-05-11 08:27:33
【问题描述】:
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; }

省略 是为了避免 Wrapped 组件导入时需要的 prop 错误。

喜欢

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);

我已将传播道具投射如下

<Component {...(props as Props)} firebase={firebase} />}

但我不确定我是否做得对。能否请您告诉我是否有任何其他方法可以解决此错误?

【问题讨论】:

    标签: reactjs typescript firebase


    【解决方案1】:

    这在编写 HOC 时经常出现。您正在查看错误并显示“我们采用Props,我们删除Props['firebase'],我们添加{firebase: Firebase | null},并且我们不确定该对象是否可分配给Props”。您可能会想,“如果我删除了firebase,然后又将其添加回来,那当然是同样的事情”。 技术上Props extends {firebase: Firebase} 意味着Props['firebase'] 可能比Firebase 更具体,在这种情况下,您提供给它的值是不够的。这种奇怪的边缘情况是您收到错误的两个原因之一。

    另一个原因是Props 不允许firebasenull,但Consumer 表示它可以有Firebasenull

    但 99.9% 的情况下它是同一件事,因此可以像您在此处所做的那样断言 {...(props as Props)}。您可能希望扩展 Props 以允许 null,但如果您知道在您的应用中它不会是 null,那么这不是问题。

    如果你让你的通用Props 代表没有firebase 的道具,你可以避免一些错误。我们没有从返回中删除firebase,而是将其添加到Component。我们从PropsOmit 任何现有的firebase 定义排除了Component 需要firebase 的某个值而不是我们提供的值的边缘情况。

    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>
    );
    

    【讨论】:

    • 谢谢@LindaPaiste。这肯定解决了我的错误。它告诉我哪里出错了,我使用了你提供的方法。我从组件中删除了 firebase。
    猜你喜欢
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 2021-10-26
    • 1970-01-01
    • 2021-09-21
    • 2021-06-23
    • 1970-01-01
    相关资源
    最近更新 更多