• React.FC报错:Type '{ children: string; }' has no properties in common with type IntrinsicAttributes
  • 发布于 1个月前
  • 56 热度
    0 评论
快速分解

截至 TypeScript 5.1 和 React 18,React.FC 现在正式宣告没问题了。

1.它不再隐式地将 children 包含在 props 类型中。

2.如果你返回 undefined、string 或 number,它不会再出错。

我仍然建议直接注释 props 而不是使用 React.FC。但是,如果你在你的代码库中使用 React.FC,就不用再删除它了。


解释
React.FC 是随 React 的 TypeScript 类型一起提供的类型。它代表了一个函数组件的类型,这是大多数现代 React 应用的基础。

它有着争议性的历史。它曾经是被推崇的组件类型化方式。后来它被认为是一种反模式。但现在,React.FC 已经改变了。自从 TypeScript 5.1 和 React 18 以来,它现在是一个完全可用的组件类型化方式。

children 不再包含在 props 类型中
对 React.FC 的主要批评来自其早期版本,它将 children 包含在 props 类型中。这意味着,如果你想要类型化一个不接受子组件的组件,你不能使用 React.FC。
// This component doesn't accept children
const Component: React.FC = () => {
  return <div />
}

// No error!
;<Component>123</Component>
这种批评足以使得 React.FC 从 create-react-app 中移除[1],这是当时最流行的创建 React 应用的方式。但是,自从 TypeScript 5.1 以来,你将从这个完全相同的代码中提示这个报错:
Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'.

你现在可以从 React.FC 返回 undefined、string 或 number
React.FC 的早期版本返回 `React.ReactElement`[2]。这意味着完全有效的组件会受到奇怪的错误的影响:
Type 'X' is not assignable to type 'ReactElement<any, string | JSXElementConstructor>'.

这是完全有效的 JavaScript,但 TypeScript 会报错,因为 123 不是 React.ReactElement 的可分配类型。

但是,自从 TypeScript 5.1 和 React 类型的最新版本以来,React.FC 现在返回 React.ReactNode。这个更宽松的类型 —— 意味着类型现在与运行时值完美匹配:
// No error!
const Component: React.FC = () => {
  return 123
}
这清除了在许多 React 应用中会出现的一个烦人的错误,并使 React.FC 更具吸引力。

你应该使用它吗?
我过去建议永远不要使用 React.FC,因为上述问题。现在,如果我在代码库中看到它,我会觉得没问题。不需要再迁移掉它了。但是 —— 我仍然不认为它是注释类型的最佳方式。这个荣誉还是属于直接给 props 类型:

这种方法更好,因为它对初学者更友好 —— 你不需要知道 React.FC 是什么,甚至不需要知道类型参数语法。如果需要的话,它也稍微容易一些重构为泛型组件。但是,要明确的是,这两种方法之间的差距从未如此接近。基于这一点,我认为你可以停止讨厌 React.FC 了。
用户评论