reactjs - ts:“道具”可以用与另一种类型无关的任意类型实例化
问题描述
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; }
添加了 Omit<Props, "firebase"> 以避免 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} />}
但我不确定我是否做得对。您能否让我知道是否有其他方法可以解决此错误?
解决方案
这在编写 HOC 时总是会出现。您正在查看错误,它显示“我们获取Props
,我们删除Props['firebase']
,我们添加{firebase: Firebase | null}
,并且我们不确定这个对象是否可以分配给Props
”。您可能会想,“如果我删除firebase
然后添加它,那当然是同一件事”。 从技术上讲,Props extends {firebase: Firebase}
这意味着它Props['firebase']
可能比 更具体Firebase
,在这种情况下,您提供给它的值是不够的。这种奇怪的边缘情况是您收到错误的两个原因之一。
另一个原因是Props
不允许 for firebase
to be null
,但 theConsumer
说它可以有Firebase
or null
。
但是 99.9% 的时间它是同一件事,所以可以{...(props as Props)}
像你在这里所做的那样断言。您可能希望扩展Props
为 allow null
,但如果您知道它不会出现null
在您的应用程序中,那么这不是问题。
如果你让你的泛型Props
代表没有firebase
. 我们没有从返回中删除firebase
,而是将其添加到Component
. 我们Omit
任何现有的定义都firebase
排除Props
了边缘情况,即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>
);
推荐阅读
- html - 如何使网格居中并将上方的行与其左侧对齐?
- javascript - 在离线桌面应用程序上显示 ZIP 存档中的图像的最有效方法是什么?
- php - 如何忽略laravel中的所有相关数据
- k6 - 在默认功能中禁用某些调用
- python - 无法获取包含请求的 url
- angular - 如何在 Angular 中包含本地库?
- python - 如何显示最大速率
- python - 在 msys2 中构建 AGG 导致错误 Invalid configuration `x86_64-pc-msys': system `msys' not Recognized
- laravel - 如何更新 Laravel 应用程序(不是作曲家依赖项)
- python - 让我的代码更快 - 将 CSV 加载到选定列上的 pandas 数据框中并合并它们