Cri*_*ian 5 typescript reactjs typescript-generics
我有一个带有签名的 TypeScript 函数:
function connectRRC<C extends ComponentType<any>>(component: C)
Run Code Online (Sandbox Code Playgroud)
目前接受任何组件。
我只想接受“props”中具有给定属性的组件。例如“id:字符串”。
正在做:
function connectRRC<C extends ComponentType<{ id: string }>>(component: C)
Run Code Online (Sandbox Code Playgroud)
不起作用,参见 这个解释。
ComponentType在 React 中定义如下:
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
interface ComponentClass<P = {}, S = ComponentState> extends StaticLifecycle<P, S> {
new (props: P, context?: any): Component<P, S>;
propTypes?: WeakValidationMap<P>;
contextType?: Context<any>;
contextTypes?: ValidationMap<any>;
childContextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
Run Code Online (Sandbox Code Playgroud)
预先感谢您的任何提示!
@sam256 提供了部分工作答案,我认为这是可以接受的。然而,我发现其他用例不起作用,没有找到合理的解释。这个TS Playground 链接展示了它们。
正如预期的那样,这有效:
class GoodComponent2 extends React.Component<{id:string, otherProp:number} & { somethingElse: boolean }> {}
connectRRC(GoodComponent2)
Run Code Online (Sandbox Code Playgroud)
但以下方法不起作用:
class BadComponent3<P = { somethingElse: boolean }> extends React.Component<{id:string, otherProp:number} & P> {}
connectRRC(BadComponent3)
class BadComponent4<P = {}> extends React.Component<{id:string, otherProp:number} & P> {}
connectRRC(BadComponent4)
Run Code Online (Sandbox Code Playgroud)
我有一个部分答案。
type RequiredProps = {id:string}
function connectRRC<T extends RequiredProps>(component: React.FC<T>){}
const goodComponent = (props:{id:string, otherProp:number}) => <div />
const badComponent = (props:{otherProp:number}) => <div />
connectRRC(goodComponent)
connectRRC(badComponent) //typescript error
Run Code Online (Sandbox Code Playgroud)
这几乎如您所愿,因为 Typescript 现在正在推断T并确保它扩展RequiredProps。
唯一的问题是,对于完全没有 props 传递的组件,这不会生成错误。这不会产生错误:
const noPropsComponent = (props:{})=><div />
connectRRC(noPropsComponent)
Run Code Online (Sandbox Code Playgroud)
原因又是逆变,至少部分原因是,尽管我不完全理解编译器在这里做什么。
似乎发生的情况是 TS 没有推断为T,{}因此无法满足约束(任何人都可以解释为什么不这样做吗?)
相反,它看起来T至少假设 是RequiredProps(约束),然后只检查是否component满足React.FC<RequiredProps>,它这样做RequiredProps是因为 处于相反的变体位置。
我不确定有什么好方法可以克服这个问题,部分原因是我不确定我是否完全理解 TS 为何会这样做。具体来说,我不明白为什么它不推断T为{}并因不满足RequiredProps约束而失败。
希望论坛里的其他人能帮忙...
| 归档时间: |
|
| 查看次数: |
604 次 |
| 最近记录: |