React子组件在TypeScript中类型推断为any的问题求助
咱们先从代码里的明显问题说起,再一步步拆解类型定义的问题:
1. 首先是语法错误导致类型解析失败
你定义MenuSubComponents接口的时候写错了语法:
interface MenuSubComponents { Item: React.FunctionComponent<;; Link: typeof Link; }
这里的<;;是完全无效的语法,TypeScript根本没法解析Item的类型,直接就把它推断成any了,这是最直接的原因。正确的写法应该是把Item的类型指向你已经定义好的Item组件:
interface MenuSubComponents { Item: typeof Item; Link: typeof Link; }
2. 错误使用了React.FC的泛型参数
你声明Menu的时候写了:
const Menu: React.FunctionComponent<{}, MenuSubComponents> & MenuSubComponents = props => <div {...props} />
但React.FunctionComponent(也就是常用的React.FC)的泛型参数只有一个,就是组件自身的Props类型,不存在第二个用来指定子组件的参数。你自己已经定义了RootFunctionComponent这个类型,它就是用来把函数组件和子组件类型合并的,所以应该直接用这个类型来声明Menu:
const Menu: RootFunctionComponent<{}, MenuSubComponents> = props => <div {...props} />;
修正后的完整代码
把这两个问题修复后,TypeScript就能正确为Menu.Item和Menu.Link提供类型检查了:
import * as React from 'react'; type RootFunctionComponent<OwnProps, SubComponents> = React.FunctionComponent<OwnProps> & SubComponents; interface ItemProps { text: string; }; interface LinkProps { href: string; } const Item: React.FunctionComponent<ItemProps> = props => <div {...props} />; const Link: React.FunctionComponent<LinkProps> = props => <div {...props} />; // 修正语法错误的子组件接口 interface MenuSubComponents { Item: typeof Item; Link: typeof Link; } // 使用自定义的RootFunctionComponent类型声明Menu const Menu: RootFunctionComponent<{}, MenuSubComponents> = props => <div {...props} />; Menu.Item = Item; Menu.Link = Link; const Test: React.FunctionComponent<{}> = () => { return <> <Menu> {/* 这里会报错:类型boolean不能赋值给string */} <Menu.Item text={false} /> {/* 这里会报错:缺少必须的href属性 */} <Menu.Link /> </Menu> </> }
总结一下原因
- 语法错误直接导致TypeScript无法解析子组件的类型,只能 fallback 到
any; - 错误地给
React.FC传了第二个泛型参数,这个参数是不存在的,应该用你自己定义的RootFunctionComponent来合并组件和子组件的类型,这样TypeScript才能正确识别子组件的props类型。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

