javascript - 打字稿类型定义:TS2604:JSX 元素类型“某物”没有任何构造或调用签名
问题描述
我在“File1”中有一个抽象类:
// File1.tsx
import * as React from 'react';
export interface IProps {
prop1: string;
prop2: number;
}
export abstract class Something extends React.Component<IProps> {
public typeName: string;
}
然后,在其他文件(File2)中,我定义了从抽象类Something扩展的无限类:
// File2.tsx
import { Something } from './File1';
export class Something1 extends Something {
public typeName: string = 'Type1';
public render() {
return <div>Something 1</div>
}
}
export class Something2 extends Something {
public typeName: string = 'Type2';
public render() {
return <div>Something 2</div>
}
}
现在,这是我的问题:在第三个文件中,我导入之前定义的类(Something1 或 Something2),然后将此类传递给 2 个不同的组件:ReadProperty 和 RenderComponent。在第一个组件中,我需要访问类的属性 typeName 并做一些事情,在第二个文件中,我需要渲染该类:
// File3.tsx
import { Something } from './File1';
import { Something1, Something2 } from './File2';
interface IReadProperty {
something: Something;
};
const ReadProperty: React.SFC<IReadProperty> = ({ something }) => {
// here i can access to property typeName. No problem here.
something.typeName // Type1 | Type2 | ... Infinite
...do some stuff
}
interface IRenderComponent {
something: Something;
}
const RenderComponent: React.SFC<IRenderComponent> = ({ something }) => {
// i need do some stuff here before render "something" component
// here i get an error when i try render the component
return <something />;
}
const Main: React.SFC = () => {
return (
<div>
<ReadProperty something={Something1} />
<RenderComponent something={Something1} />
</div>
);
}
但是当我尝试在 RenderComponent 中渲染组件时,出现以下错误:TS2604:JSX 元素类型“某物”没有任何构造或调用签名。
这里有什么问题?我将类型'something'定义为抽象类Something,因为我可以定义从Something扩展的无限类,所以我不能定义使用:something:Something1 | 东西2 | 东西50 ...;
这是我尝试做的一个例子:https ://codesandbox.io/s/18yzvkx8jj
解决方案
问题在于,在您的定义中IRenderComponent
,您说的something
是 的实例,Something
而您想要的是构造函数类型。另一件事是,当您尝试使用小写名称实例化组件时,React 通常会抱怨。尝试这个:
interface IRenderComponent {
Something: new (props: IProps) => Something1;
};
const RenderComponent: React.SFC<IRenderComponent> = ({ Something }) => {
return <Something prop1="foo" prop2={3} />;
}
对于IReadProperty
,看起来您确实想要一个实例Something
(因为您想要访问typeName
,它是一个实例属性)。但是,您实际上不能传递实例化的组件:
<ReadProperty something={<Something1 prop1="" prop2={3} />;} /> //Error
这是因为<Something1 ... />
它实际上不是一个实例Something1
- 它是一个JSX.Element
. 您可以传递 的实例Something1
,如下所示:
<ReadProperty something={new Something1({prop1: "", prop2: 3})} />
但我想这不是你想要的,因为你实际上不能在渲染中使用生成的实例。
解决问题的最佳方法IReadProperty
取决于您实际想要完成的任务。一般来说,React 更倾向于组合而不是继承和反射,因此可能更容易考虑如何通过从基础组件开始并组合它们或使用高阶组件来实现您的目标。
推荐阅读
- ant - Apply with parameter and input file redirector does not work
- android - 将文件夹的内容复制到android中的其他文件夹
- c# - cannot convert from 'Microsoft.Xrm.Sdk.Query.QueryExpression' to 'Microsoft.Crm.Sdk.Query.QueryBase
- java - 无法从适配器检索数据并将其显示为片段
- python - 没有这样的文件或目录:'/dev/hidraw0'
- python - What's the __fields__ does in python?
- c++ - 如何停止在 C++ 中调用不兼容的方法?
- php - 想要使用 wordpress 中的重定向插件将一堆 url 批量重定向到另一个 url 结构
- python - 将 FreeCAD 导入 Python 以在外部脚本中使用
- dask - dask:关闭悬空流
开始
dask
LocalCluster
时from dask.distributed import Client client = Client()
并在中断
jupyter
内核并重新运行单元