TypeScript返回React组件类的工具函数类型报错求助
你遇到的问题其实是TypeScript对泛型类构造函数类型进行严格类型检查的结果,并不是TypeScript的Bug。让我拆解一下原因和解决方案:
为什么原来的写法会报错?
typeof React.PureComponent代表的是泛型PureComponent类的构造函数类型,它的构造签名可以理解为:
new <P, S>(props: Readonly<P>) => React.PureComponent<P, S>
这个构造函数期望能接受任意类型的props(泛型参数P),并返回对应props类型的PureComponent实例。
而你的FooOne和FooTwo是具体的非泛型子类,它们的构造签名是:
new (props: Readonly<{}>) => FooOne // FooTwo同理
它们只能接受空对象作为props,返回的实例也是固定类型的。
TypeScript认为这两种构造函数类型不兼容:泛型构造函数的返回实例PureComponent<P, S>的props是任意的P,而子类实例的props是固定的空对象,所以无法将子类的构造函数赋值给泛型的typeof React.PureComponent类型。
解决方案:使用React内置的ComponentClass类型
React已经为我们提供了专门表示组件类的类型React.ComponentClass,它完美适配这种场景。修改你的函数返回类型即可:
import React from 'react'; class FooOne extends React.PureComponent { render(): React.ReactElement { return null; } } class FooTwo extends React.PureComponent { render(): React.ReactElement { return null; } } // 使用React.ComponentClass作为返回类型 function getFooClass(condition: boolean): React.ComponentClass { return condition ? FooOne : FooTwo; } const SomeFooClass = getFooClass(true); // 实例化时注意传入符合要求的props(这里是空对象) const instance: React.PureComponent = new SomeFooClass({});
如果需要更精确地约束props和state类型(比如你的组件有特定props),可以给ComponentClass传入泛型参数:
// 假设组件接受{ name: string }类型的props type FooProps = { name: string }; class FooOne extends React.PureComponent<FooProps> { /* ... */ } class FooTwo extends React.PureComponent<FooProps> { /* ... */ } function getFooClass(condition: boolean): React.ComponentClass<FooProps> { return condition ? FooOne : FooTwo; }
额外说明:类型断言的临时方案
如果你非要使用typeof React.PureComponent作为返回类型,也可以通过类型断言绕过检查,但这不是推荐的做法(因为会丢失类型安全性):
function getFooClass(condition: boolean): typeof React.PureComponent { return (condition ? FooOne : FooTwo) as typeof React.PureComponent; }
总的来说,这是TypeScript在泛型类型系统上的严格检查导致的,属于设计上的限制而非Bug,使用React.ComponentClass是最规范的解决方式。
内容的提问来源于stack exchange,提问作者Ivanf

