TypeScript React组件如何定义接收任意返回值函数的属性类型
问题根源
你遇到的报错本质上不是类型定义的问题,是JSX传参的逻辑问题:
- 当你写
<MyComponent getData={function1()}/>时,JSX渲染阶段会直接执行function1(),把函数执行后的返回值传给getData,而非传入function1本身。如果function1的返回值不是函数类型,你在组件内调用getData()自然会抛出getData is not a function的错误。 - 你后续包一层箭头函数
() => function1()的写法是正确的,此时传给getData的是未执行的函数实例,组件内部调用时才会触发function1的执行。
解决方案,根据你的实际需求二选一:
方案1:组件内不需要二次调用getData,只需要拿到函数执行结果
直接修改类型定义,把getData的类型设为你期望的函数返回值类型即可,组件内直接使用getData不要加括号调用:
interface MyComponentProps { // 如果你不需要限制返回值类型就写any,要限制就替换成对应类型,比如string、number等 getData: any; }
此时你最开始的写法可以正常运行:
<MyComponent getData={function1()}/> <MyComponent getData={function2(1,2)}/> <MyComponent getData={function3("hello")}/>
方案2:组件内需要调用getData,同时要支持「传函数本身」和「传执行结果」两种用法
把类型定义为函数和返回值的联合类型,组件内使用前做类型判断:
类型定义:
interface MyComponentProps { getData: ((...args: any[]) => any) | any; }
组件内使用逻辑:
// 封装取值方法统一处理两种入参形式 const getResult = () => { if (typeof getData === 'function') { return getData(); } return getData; }
此时两种传参方式都可以正常运行:
// 传函数本身,组件内部调用时再传参 <MyComponent getData={function2}/> // 直接传执行后的结果 <MyComponent getData={function2(1,2)}/>
额外提示
如果你就是要传带固定参数的函数本身,不想写额外的箭头函数,可以直接把参数放到组件内部调用的位置,写法如下:
// 传函数本身,不要加括号执行 <MyComponent getData={function2}/>
// 组件内部调用时传对应参数 const result = getData(1,2);
内容的提问来源于stack exchange,提问作者Purus
相关产品推荐
相关产品推荐

