TypeScript TSX中如何为匿名函数传递泛型?解决JSX报错
解决TSX中泛型匿名函数的JSX解析冲突问题
这个报错我太熟悉了——TSX语法里的<符号会被优先解析为JSX标签的起始,所以你写的<T>被编译器误认为是要渲染一个叫T的JSX元素,找不到闭合标签就抛出了JSX element 'T' has no corresponding closing tag错误。下面给你几个靠谱的解决办法:
方法1:给泛型参数加个逗号(最简洁的技巧)
这是TSX里处理泛型箭头函数最常用的小hack,只要在泛型参数后面加个逗号,编译器就会明白这是泛型参数列表,而不是JSX标签:
export const withComponent = <T,>(Component: React.ComponentType<T>) => (props: any) => ( <shortcutContext.Consumer> {addShortcut => <Component addShortcut={addShortcut} {...props} />} </shortcutContext.Consumer> );
方法2:给泛型参数添加extends约束
如果觉得逗号的写法不太优雅,可以给泛型T加一个类型约束,比如让它继承object(毕竟组件props基本都是对象类型),这样编译器也能正确识别这是泛型定义:
export const withComponent = <T extends object>(Component: React.ComponentType<T>) => (props: any) => ( <shortcutContext.Consumer> {addShortcut => <Component addShortcut={addShortcut} {...props} />} </shortcutContext.Consumer> );
方法3:改用具名包裹函数
要是你完全不想用上面的语法技巧,也可以把返回的匿名箭头函数改成具名函数,这样泛型的写法就和普通TypeScript文件完全一致了,不会有解析冲突:
export const withComponent = <T>(Component: React.ComponentType<T>) => { function WrappedComponent(props: any) { return ( <shortcutContext.Consumer> {addShortcut => <Component addShortcut={addShortcut} {...props} />} </shortcutContext.Consumer> ); } return WrappedComponent; };
额外的类型优化建议
顺便提一句,你现在用any作为props的类型有点不严谨,建议改成和泛型T结合的类型,比如用Omit<T, 'addShortcut'>来表示不需要传入addShortcut(因为HOC会注入这个属性):
export const withComponent = <T extends { addShortcut?: unknown }>(Component: React.ComponentType<T>) => (props: Omit<T, 'addShortcut'>) => ( <shortcutContext.Consumer> {addShortcut => <Component addShortcut={addShortcut} {...props} />} </shortcutContext.Consumer> );
内容的提问来源于stack exchange,提问作者dagda1
相关产品推荐
相关产品推荐

