网站搜索

reactjs - 如何将泛型限制为可以作为 React 组件 props 的类型?


我刚刚完成了与 TypeScript 编译器的斗争,去创建一个组件,该组件将另一个组件作为 prop,然后要求将所有那个组件的 props 作为 prop 传递给它。(用例是用于 Gatsby 的 <PrivateRoute> 组件)。

我设法让它实际运行了,但问题是我不知道为什么这会有效。

这里是一个简化的例子:

包装组件和定义的属性:

type WrapperProps<T> = { component: React.ComponentType<T> } & T;

const Wrapper = <T extends object>({
    component: Component,
    ...rest
}: WrapperProps<T>) => {
    return <Component {...(rest as T)} />;
};

以及预期用途:

interface person {
    name: string;
    age: number;
}

const ShowPerson = ({ name, age }: person) => {
    return (
        <h1>
            {name}, {age}
        </h1>
    );
};

const Display = () => {
    return <Wrapper component={ShowPerson} name="T" age={12} />;
};

我无法弄明白为什么它能工作的部分是在包装组件中的泛型约束。如果我移除 <T extends object>,我会得到一个错误:“将类型 'Omit<WrapperProps<T>,"component">' 转换为类型 'T' 可能是一个错误,因为两种类型都没有足够的重叠”

现在,可以理解为什么泛型需要受到约束,但有没有比使用 <T extends object> 更好的约束?为什么 <T extends {}> 不起作用?对于 React 组件的 props,有什么可接受且更好的泛型约束吗?extends object 对我来说感觉并不是正确的解决方案。

编辑 这也可以通过将 ...rest as unknown as T 转换来实现,但我仍然难以理解它的本质:

const Wrapper = <T,>({
    component: Component,
    ...rest
}: WrapperProps<T>) => {
    return <Component {...(rest as unknown as T)} />;
};

TypeScript 游乐场示例