当我使用具有此更高阶的泛型类型时,我收到此错误 控制在React& TypeScript(使用@ types / react 15.0.27):
TS2322:Type '{}' is not assignable to type 'IntrinsicAttributes &
IntrinsicClassAttributes<Component<ITypeComponentProps, ComponentState>> & ...'.
Type '{}' is not assignable to type 'Readonly<ITypeComponentProps>'.
Property 'data' is missing in type '{}'.
我希望我的withTestData
函数返回类型React.ComponentClass<ITestComponentProps>
的控件(即带有空道具),但它告诉我需要在道具中传递data
。但是,当我替换泛型类型ITypeTestProps<TData>
时,它按预期工作
下面是非泛型类型ITypeTestProps
,TData类型为string
。
withTestData
看起来有点令人费解,但是它做了一些相当简单的事情 - 它需要一个组件,它需要P & ITypeTestProps<TData>
类型的道具和
将其包装在期望类型为P
的道具的组件中。在此测试用例中,P
为ITestComponentProps
。
这是带有错误的版本:
import * as React from "react";
import {mount} from "enzyme";
interface ITestComponentProps {}
type HOC<PWrapped, PHoc> = React.ComponentClass<PWrapped & PHoc> |
React.SFC<PWrapped & PHoc>;
export interface ITypeTestProps<TData> {
data: TData;
}
export function withTestData<P, S, TData>(Component: HOC<P,
ITypeTestProps<TData>>, data: TData):
React.ComponentClass<P> {
class C extends React.Component<P & ITypeTestProps<TData>, S> {
public render(): JSX.Element {
return (
<Component data={data} {...this.props as any} />
);
}
}
return C;
}
type ITypeComponentProps = ITestComponentProps & ITypeTestProps<String>;
class TestComponent extends React.Component<ITypeComponentProps, {}> {
public render(): JSX.Element {
return (<div>Hello, {this.props.data}</div>);
}
}
describe("withTestData()", () => {
it("wraps a component", () => {
const data: string = "World";
const WrappedTestComponent = withTestData(TestComponent, data);
// The type mismatch occurs here:
const wrapper = mount(<WrappedTestComponent />);
expect(wrapper.text()).toContain(`Hello, ${data}`);
});
});
我可以通过像这样投射控件来解决它,但我想消除演员:
const WrappedTestComponent = withTestData(TestComponent, data) as
React.ComponentClass<ITestComponentProps>
修改
这是一个按照我的预期运作的版本 - 它删除了数据&#34;从生成的界面。唯一的区别是类型不是通用的。
import * as React from "react";
import {mount} from "enzyme";
interface ITestComponentProps {}
type HOC<PWrapped, PHoc> = React.ComponentClass<PWrapped & PHoc> |
React.SFC<PWrapped & PHoc>;
export interface ITypeTestProps {
data: string;
}
export function withTestData<P, S, TData>(Component: HOC<P, ITypeTestProps>, data: TData):
React.ComponentClass<P> {
class C extends React.Component<P & ITypeTestProps, S> {
public render(): JSX.Element {
return (
<Component data={data} {...this.props as any} />
);
}
}
return C;
}
type ITypeComponentProps = ITestComponentProps & ITypeTestProps;
class TestComponent extends React.Component<ITypeComponentProps, {}> {
public render(): JSX.Element {
return (<div>Hello, {this.props.data}</div>);
}
}
describe("withTestData()", () => {
it("wraps a component", () => {
const data: string = "World";
const WrappedTestComponent = withTestData(TestComponent, data);
// The type mismatch occurs here:
const wrapper = mount(<WrappedTestComponent />);
expect(wrapper.text()).toContain(`Hello, ${data}`);
});
});
从零开始运行此示例:
$ npm install -g create-react-app
$ create-react-app my-app --scripts-version=react-scripts-ts
$ cd my-app/
$ npm install @types/react@15.0.27 enzyme --dev
将上述代码复制到文件src/demo.test.tsx
$ npm test
答案 0 :(得分:0)
错误正确警告您错过了为ITypeTestProps
接口的强制属性提供值。
因此,为了解决问题(如果您的业务逻辑没有问题),您可以在data
接口中将ITypeTestProps
声明为可选属性:
export interface ITypeTestProps<TData> {
data?: TData;
}