使用 TypeScript 反应道具类型 - 如何拥有函数类型?

Posted

技术标签:

【中文标题】使用 TypeScript 反应道具类型 - 如何拥有函数类型?【英文标题】:React prop types with TypeScript - how to have a function type? 【发布时间】:2019-12-21 22:43:43 【问题描述】:

对于使用 TypeScript 的 React 属性类型的函数类型是否有最佳实践?

我以为这会起作用,但实际上它出错了:

type Props = 
  onClick: Function
;

const Submit = ( onClick : Props) => 
  return (
    <button type="button" onClick=onClick>
      click me
    </button>
  );

在这个线程之后,我得到了它的工作,但它似乎不必要地冗长: https://github.com/Microsoft/TypeScript/issues/20007

type Props = 
  onClick: (...args: any[]) => any;
;

const Submit = ( onClick : Props) => 
  return (
    <button type="button" onClick=onClick>
      click me
    </button>
  );

【问题讨论】:

【参考方案1】:

关于Function 和最佳实践

Function 在实践中的类型安全性不足,是所有函数的超类型。您最好将其替换为 function type - 请参阅下方的“解决方案”部分。

在上面的示例中,Function 不能分配给更窄的 onClick 函数类型,这会导致手头的错误 (Playground example)。

除了mentioned issue,,下面是TypeScript docs 对Function 的评价:

这是一个无类型的函数调用,通常最好避免,因为任何返回类型都是不安全的。如果需要接受任意函数但不打算调用它,() =&gt; void 类型通常更安全。

typescript-eslint 已丢弃 Function 使用ban-types 规则,emitting following message 使用默认配置(另请参阅here):

Function 类型接受任何类似函数的值。它在调用函数时不提供类型安全,这可能是常见的错误来源。 如果您希望函数接受某些参数,则应显式定义函数形状。

更好的解决方案

React 已经自带built-in event handler-types 来处理common events。

例如click (Playground):
type Props = 
  onClick: React.MouseEventHandler<htmlButtonElement>
;

const Submit = ( onClick : Props) => <button onClick=onClick> click </button>
更通用的替代方法是使用function types,如下所示:
type Props =  
  onClick: (event: React.MouseEvent<HTMLElement>) => void
;

voidany 更严格。不可能在回调中意外返回值,而 any 则可能发生这种情况。

总之,我们采用 TypeScript 的打字功能,而不是使用 Functionany。 现在已知参数为MouseEvent,返回类型为void,将其标识为回调。

相关

Typescript: How to define type for a function callback (as any function type, not universal any) used in a method parameter

【讨论】:

【参考方案2】:

您可以像这样简单地编写它,这样可以防止任何事情并且更有说服力。特别是对于自定义函数:

界面道具 onClick: (e: 事件) => void;

这将告诉调用组件,onClick 将期望什么以及参数是什么。

希望这会有所帮助。编码愉快。

【讨论】:

以上是关于使用 TypeScript 反应道具类型 - 如何拥有函数类型?的主要内容,如果未能解决你的问题,请参考以下文章

使用多种道具类型反应 Typescript 组件

TypeScript 条件类型:从反应组件中提取组件道具类型

如何将儿童类型传递给 HOC 反应的道具

如何在带有打字稿的反应功能组件中定义自定义道具?

反应原生 Typescript Touchableopacity 道具错误

打字稿反应组件中的反应/道具类型eslint错误