TypeScript typeof泛型类的类型

时间:2019-07-25 11:01:38

标签: reactjs typescript

我想创建一个函数,该函数将返回类型为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
}

2 个答案:

答案 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
}