首页 > 解决方案 > 通用无状态组件 React 的类型?或在打字稿中扩展通用函数接口以具有进一步的通用性?

问题描述

问题: 的接口Stateless Functional Component给出为

interface SFC<P = {}> {
    (props: P & { children?: ReactNode }, context?: any): ReactElement<any> | null;
    propTypes?: ValidationMap<P>;
}

我的组件的 prop 类型也是通用的:

interface Prop<V>{
    num: V;
}

如何正确定义我的组件?作为:

const myCom: <T>SFC<Prop<T>> = <T>(props: Prop<T>)=> <div>test</div>

character 27给出了一个错误Cannot find name 'T'

这是:修改示例的 Typescript Playground

我的发现

1:Typescript 2.9.1 支持有状态的通用组件:http ://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#generic-type-arguments-in-jsx-elements

class myCom<T> extends React.Component<Prop<T>, any> {
   render() {
      return <div>test</div>;
   }
}

2:扩展SFC以创建以下答案中提到的新接口将使组件的道具类型为anyTypescript React无状态函数与我不想要的通用参数/返回类型。我想为我的道具提供正确的类型

标签: javascriptreactjstypescriptgenerics

解决方案


你不能像这样使用泛型:

const myCom: <T>SFC<Prop<T>> = <T>(props: Prop<T>)=> <div>test</div>

TypeScript 规范指出:

形式的构造

< T > ( ... ) => { ... }

可以被解析为带有类型参数的箭头函数表达式或应用于没有类型参数的箭头函数的类型断言。

资源; 微软/TypeScript 规范.md

您的声明与 TypeScript 规范中定义的模式不匹配,因此它不起作用。

但是,您可以不使用 SFC 接口而只自己声明它。

interface Prop<V> {
    num: V;
}

// normal function
function Abc<T extends string | number>(props: Prop<T>): React.ReactElement<Prop<T>> {
    return <div />;
}

// const lambda function
const Abc: <T extends string | number>(p: Prop<T>) => React.ReactElement<Prop<T>> = (props) => {
   return <div />
};

export default function App() {
    return (
        <React.Fragment>
            <Abc<number> num={1} />
            <Abc<string> num="abc" />
            <Abc<string> num={1} /> // string expected but was number
        </React.Fragment>
    );
}

推荐阅读