我想创建一个函数,该函数将返回类型为React Component的类型,该函数必须实现特定的props接口。
我想返回一个类型,而不是该类型的实例。
因此,此:
interface INameProps {
name: string;
}
interface ITypeProps {
type: string;
}
class Component1 extends React.Component<INameProps> {}
class Component2 extends React.Component<INameProps> {}
class Component3 extends React.Component<ITypeProps> {}
我想创建一个函数,该函数可以返回组件,props接口为此扩展了INameProps
到目前为止,我已经弄清楚了:
export function getComponents<T extends INameProps, S extends any>(): React.Component<T, S> {
return Component1; // should be fine
return Component2; // should be fine
return Component3; // should not be allowed, since T for Component3 does not extend INameProps
}
但这是不正确的-此函数的返回类型是这些组件的实例。
要获取类型,我想我只需要像这样添加typeof
关键字:
export function getComponents<T extends INameProps, S extends any>(): typeof React.Component<T, S>
但是TypeScript不喜欢,我在React.Component之后添加了泛型<T, S>
。
当我这样定义它时,它会编译:
export function getComponents<T extends INameProps, S extends any>(): typeof React.Component
但这不能满足我的要求-像这样的返回函数类型是任何React.Component的类型。
我该怎么写?
编辑:
我环顾四周,发现React.ComponentType(对于Flow,我没有看到有关TypeScript的任何文档)
结果是,答案很简单。我试图使用高级类型的TypeScript提出自己的方式,但是React已经想到了这一点-
export function getComponent(): React.ComponentType<INameProps> {
return Component1; // allowed
return Component2; // allowed
return Component3; // not allowed, since props for Component3 does not extend INameProps
}
答案 0 :(得分:2)
某个类C
的构造函数(或类型)可以表示为new () => C
,加上减号构造函数args和泛型类型。
不过,您的方法在这里行不通。当您具有通用函数时,则由调用者决定选择其通用类型。有时它们是由编译器推断的,但无论如何,都是由调用者控制它们的。因此有人可能将您的函数称为getComponent<SomeIrrelevantType>
,那么您想返回什么?在运行时,您甚至无法看到将通用类型设置为不相关的内容。
您可以使用的方法与此类似:
export function getNamePropsComponents():
(new () => React.Component<INameProps, any>)[] {
return [Component1, Component2]; // should be fine
return [Component3]; // doesn't compile
}
答案 1 :(得分:0)
我环顾四周,发现React.ComponentType(对于Flow,我没有看到有关TypeScript的任何文档)
结果是,答案很简单。我试图使用高级类型的TypeScript提出自己的方式,但是React已经想到了这一点-
export function getComponent(): React.ComponentType<INameProps> {
return Component1; // allowed
return Component2; // allowed
return Component3; // not allowed, since props for Component3 does not extend INameProps
}