泛型类型变量可用于函数和类型声明,如接口Sample1
和Sample2
. 但是当你实际使用/调用/调用泛型类型时,你必须指定一个具体的类型参数而不是P
.
React.SFC
- 无状态函数组件类型 - 是一个接口声明,因此在const
赋值中使用它需要一个具体的类型P
。
我想到的唯一解决方案是让它SFC
看起来像function
ts-compiler的类型,因为函数声明/表达式可以分配泛型类型参数。有关 一些示例,请参阅Typescript 文档。
通用证监会声明
React.SFC
在您的作业中省略类型注释const SampleSFC
:
const SampleSFC = <P extends {}>(props: Sample2<P>) => <div>{props.prop1} </div>;
注意:<P extends {}>
由于与泛型的 JSX/TSX 兼容性问题,需要该部分,请参阅本文末尾。
这样,您的组件仍然是一个普通的函数。如果您需要 中的其他成员React.SFC
,请将它们添加到您的props中。例如,如果children
需要:
const SampleSFC = <P extends {}>(props: Sample2<P> & { children?: ReactNode })
=> <div >{props.prop1} </div>;
通用 SFC 用法
从Typescript 2.9 开始,可以直接在 JSX 中设置类型参数。
const MyApp: React.SFC<{}> = (props) => {
return <SampleSFC<number> prop2="myString" prop1={1} />
}
备择方案
1.) 如果您不喜欢这些怪癖,切换到类组件会很容易。
class SampleSFCClass<P> extends React.Component<Sample2<P>> {
render() {
return <div>{this.props.prop1}</div>
}
}
const MyApp2: React.SFC<{}> = (props) => {
return <SampleSFCClass<number> prop2="myString" prop1={1} />
}
2.) 您甚至可以将 包装SFC
在另一个函数中。
const withGeneric: <P>() => React.SFC<Sample2<P>> = <P extends {}>() => {
return (props) => <div> {props.prop1} {props.prop2} </div>;
}
const SampleSFCCalled: React.SFC<Sample2<string>> = withGeneric<string>();
const MyApp: React.SFC<{}> = (props) => {
return <SampleSFCCalled prop2="myString" prop1="aString" />
}
它会起作用,但缺点可能是性能略有下降,因为该SFC
功能总是在父组件的每个渲染周期中重新创建。
JSX/TSX 与泛型的兼容性问题:
在某些情况下,由于语法不明确,Typescript 在结合 JSX/TSX(直到最近的 3.0.1)解析泛型时似乎存在问题。编译错误将是:
“JSX 元素没有相应的结束标记。”
一位贡献者建议function
在这种情况下使用语法(请参阅问题)。
当您坚持使用箭头函数时,解决方法是让类型参数从 object 扩展(显示在此处或此处)以阐明它是通用 lambda 而不是 JSX 标记:
<P extends {}>
或者 <P extends object>
希望,这有帮助。