【发布时间】:2021-06-23 21:41:04
【问题描述】:
我有这段代码(这是我真实代码的简化版本,希望我没有删除任何重要的东西)
import React, { ReactElement, ReactNode, createElement } from "react";
interface WithChildren {
children: ReactNode;
}
type WrapperType<WTProps> = (
props: WithChildren & WTProps
) => ReactElement | null;
interface SetProps<P> {
wrap: WrapperType<P>;
children: ReactNode;
[x: string]: unknown;
}
export function Set<WProps>(props: SetProps<WProps>) {
const { wrap, children, ...rest } = props;
return createElement(wrap, { ...rest, children });
}
interface WrapperProps {
children: ReactNode;
foo: string;
}
const ChildWrapper: React.FC<WrapperProps> = ({ foo, children }) => {
return (
<div>
<h1>ChildWrapper</h1>
<p>{foo}</p>
{children}
</div>
);
};
export default function App() {
return (
<Set wrap={ChildWrapper} foo="bar">
<h1>Hello CodeSandbox</h1>
</Set>
);
}
createElement 行给出了这个错误
No overload matches this call.
The last overload gave the following error.
Argument of type '{ children: React.ReactNode; }' is not assignable to parameter of type 'Attributes & WithChildren & WProps'.
Type '{ children: React.ReactNode; }' is not assignable to type 'WProps'.
'WProps' could be instantiated with an arbitrary type which could be unrelated to '{ children: React.ReactNode; }'
我可以通过这样的类型转换来“修复”它
return createElement(wrap, { ...rest, children } as WProps & WithChildren);
但这消除了类型安全性。
我发现了这个类似的问题ts: 'Props' could be instantiated with an arbitrary type which could be unrelated to another type,他们使用Omit<> 来解决它。但我不知道如何在我的情况下应用它。
有没有什么方法可以在不进行类型转换的情况下做到这一点?
编辑:这是一个代码框,显示错误https://codesandbox.io/s/optimistic-microservice-ck7nf?file=/src/App.tsx
以及错误信息的截图
【问题讨论】:
-
你的代码中好像没有这个错误
-
@zixiCat 我添加了一个代码框链接,您可以在其中看到错误
-
我开始给你写一个很长的答案,但实际上我现在所处的位置
children的类型被推断为Set的孩子的类型,而不是ChildWrapper所以WrapperProps必须是JSX.Element而不是ReactNode。 tsplay.dev/WKkpzW我看看能不能更好的控制推理。
标签: reactjs typescript generics typescript-typings typescript-generics