在 React 中,经常会有这样的场景:通过某一个参数是否是真值,来决定某一个元素是否需要显示出来。
以 Ant Design 为例,Tooltip 的定义中,就包含了 title 这个参数,用于决定是否显示 Tooltip 及显示什么。如果传递的是 false,null 或者 undefined,那么最终 Tooltip 就不会被显示出来。
常用的调用形式可能如下:
<Tooltip title={!this.state.hide && 'text'} />在最初 Ant Design 对此的定义上,使用了如下的 TypeScript 类型定义:
interface Props {
  // ...
  title?: React.ReactNode | RenderFunction;
  // ...
}这里,title 的定义用到了“可选参数”。看上去,是符合预期的行为,然而这里有几个细节值得注意:
React.ReactNode的定义是:
type ReactNode =
  ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;可以看到,即使不是可选参数,undefined 等一系列值也是可以赋予给 title 的;
title?: string和title: string | undefined之间存在着细微的差别。
这里展开对比一下 title?: string 和 title: string | undefined 之间的细微差别。如果定义的类型是 title?: string,那么,以下的调用方式都是正确的:
- 传递字符串作为参数:
 
<Tooltip title="string" />- 传递 
undefined作为参数: 
<Tooltip title={undefined} />- 不传递参数:
 
<Tooltip />而如果是 title: string | undefined,那么上面的第三种方案(即不传参数)就是不可行的。
还是以 Tooltip 为例,显然前两种调用方法都是真实存在的场景,毕竟 Tooltip 可能是需要根据外部条件来选择性展示的;但是对于第三种场景,即不提供 title 数据、一直保持不渲染 Tooltip 的状态,可以认为是有错误的,应该由 TypeScript 进行检查并报错。
故,改成以下这种形式就可以了,毕竟 React.ReactNode 就允许了 undefined 的使用:
interface Props {
  // ...
  title: React.ReactNode | RenderFunction;
  // ...
}Ant Design 对这种情况进行了修正。