繁体   English   中英

在 Typescript 中使用 React Props 展开运算符(错误:...可以使用约束 {} 的不同子类型进行实例化)

[英]Spread operator with React Props in Typescript (error: ...could be instantiated with a different subtype of constraint {})

我正在尝试使用 Typescript 在 React 中编写一个高阶组件,该组件接收道具,“消耗”其中一个,然后将其余部分传递给子组件。

function testConnect<T>(Child: React.ComponentType<T>): React.ComponentType<T> {

  type InitialState = {
    iS: StoreShape.State;
  };

  type LAP = InitialState & T;

  const Connector = (props: LAP) => {
    const { iS, ...rest } = props;
    // do something with iS
    return (
      <Child // Visual Studio complains about this line.
        {...rest}
      />
    );
  };

  return Connector;
}

然而,这失败并出现错误: 'Pick<LAP, Exclude<keyof T, "iS">>' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'

我不仅想知道我是否可以做些什么,而且还想知道为什么会发生这种情况。

实际上,Typescript 正在捕获您的组件的问题:

 const Component = testConnect(({ iS }) => <div>{iS}</div>);

 <Component iS={...} />

所以你要么必须

(a) 将所有道具(而不仅仅是休息)传递给组件。

   <Child   {...props} />

(b) 通过从 T 中排除键iS ,确保不能传入名为“iS”的 prop:

 testConnect<T>(Child: React.ComponentType<Omit<T, "iS">>>): React.ComponentType<T> {

这是您问题的解决方案,不是最优雅的解决方案,但它停止抱怨:

type InitialState = {
    iS: StoreShape.State;
};

function testConnect<T>(Child: React.ComponentType<T>): React.ComponentType<T> {
    const Connector = (props: InitialState & Exclude<T, "iS">) => {
        const isT = (object: any): object is T => {
            return !("iS" in object);
        };

        const { iS, ...rest } = props;

        if (isT(rest)) {
            return (
                <Child // Visual Studio complains on this line.
                    {...rest}
                />
            );
        }

        return <Child {...props} />;
    };

    return Connector;
}

对于您的代码停止抱怨,您需要修复将道具传递给Child组件的方式。 他接受类型为T props 但是在你的情况下, rest不是T类型(或者至少 TS 编译器不够聪明,无法弄清楚),它的类型是Pick<LAP, Exclude<keyof T, "iS">>因为你使用了rest operator .

我的解决方案的想法只是让编译器知道rest是类型T ,使用自定义类型保护函数,但您可以使用其他方法,例如类型转换:

<Child
  {...((rest as unknown) as T)}
/>

我希望它能帮助你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM