对React HOC的包装组件进行类型检查失败

时间:2019-01-17 20:16:38

标签: typescript

使用此代码,React HOC函数中的

component参数无法进行类型检查:

import * as React from 'react';

interface FooProps {
  foo: string;
  bar: string;
}

function withProps<P extends FooProps>(
  Comp: React.ComponentType<P>
) {
  return class extends React.Component {
    render() {
      return <Comp foo="foo" bar="bar"/>  // "Comp" fail typecheck
    }
  }
}

我原以为P extends FooProps约束就足够了,但还不够。

我收到此错误:

Type '{ foo: string; bar: string; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
  Property 'foo' does not exist on type 'IntrinsicAttributes & P & { children?: ReactNode; }'.

Visual Studio Code智能感知成功将foobar道具分别检测为FooProps.fooFooProps.bar,但在Comp上失败

为什么这不符合预期?

我想我不了解泛型函数如何推断泛型变量类型。

注意:使用Comp: React.ComponentType<FooProps>可以正常工作。

3 个答案:

答案 0 :(得分:0)

好的。

由于打字稿投诉,我仅在道具foobar上选择声明的道具,但是extends暗示P类型的道具可能更多。

这可以通过使用...this.props从P传递其余(未知道具)来解决。像这样:

import * as React from 'react';

interface FooProps {
  foo: string;
  bar: string;
}

function withProps<P extends FooProps>(
  Comp: React.ComponentType<P>
) {
  return class extends React.Component<P> {
    render() {
      return <Comp {...this.props} foo="foo" bar="bar" />
    }
  }
}

请参见...this.props中的<Comp .../>,以及如何将P道具也需要传递到HOC组件。

答案 1 :(得分:0)

再次回答我自己。

答案不好,因为...this.props“影子”需要道具及其类型。现在,我可以输入此内容并进行类型检查而不是失败,并且应该。

    render() {
      return <Comp {...this.props} foo1="foo" bar={8} /> // Should FAIL typecheck
    }

然后,以上答案是错误的。

答案 2 :(得分:0)

正确的答案是我的初始代码是正确的:

import * as React from 'react';

interface FooProps {
  foo: string;
  bar: string;
}

function withProps<P extends FooProps>(
  Comp: React.ComponentType<P>
) {
  return class extends React.Component {
    render() {
      return <Comp foo="foo" bar="bar"/>  // "Comp" typecheck OK
    }
  }
}

问题是从3.1.6到3.3-RC的TS上的错误:https://github.com/Microsoft/TypeScript/issues/28938

返回3.1.4的工作与预期的一样。

**注意:正在使用Typescript 3.3.0-dev.20190117