TypeScript - 类型 'undefined' 不能分配给类型 'ReactElement'

时间:2021-05-24 16:05:50

标签: javascript reactjs typescript

我的反应项目中有这个错误输出

TypeScript error
Argument of type 'ReactNode' is not assignable to parameter of type 'ReactElement<any, string | JSXElementConstructor<any>> | ReactElement<any, string | JSXElementConstructor<any>>[]'.
  Type 'undefined' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | ReactElement<any, string | JSXElementConstructor<any>>[]'.

但我无法找出我的代码到底有什么问题,这里是:

           const { children } = props;

  > 19 |   const mapChildren = React.Children.map(children, (tread: ReactElement) => tread);
       |                                          ^
    20 |   const child = mapChildren.filter((tread: ReactElement) => tread.props.id === currentTread)[0];
    21 | 
    22 |     useEffect(() => {
              init(mapChildren);
             }, []);

children 元素到底有什么问题?

1 个答案:

答案 0 :(得分:2)

修复

这就足够了并且类型安全:

const mapChildren = React.Children.map(children, (tread) => tread);

tread 的类型由 Children.map 规定并由 TypeScript 推断。

为什么?

children 本身没有任何问题。

但我们必须确保 children 的类型与传递给 Children.map 的函数的类型匹配:

map<T, C>(
  children: C | C[], 
  fn: (child: C, index: number) => T
): C extends null | undefined 
  ? C 
  : Array<Exclude<T, boolean | null | undefined>>;

(Source)

这意味着 childfn 参数的类型必须与 children 的类型相同(无论 children 是单个对象还是一个数组)。

当我们将 (tread: ReactElement) => tread 作为 fn 传递时会发生什么?

我们是说 fn 将只接受 ReactElement 的孩子。

但是,childrenReactNode(除非您明确地以不同的方式键入),因此由于类型不匹配,React 无法通过 fn 传递它们。

什么是类型不匹配?

ReactElement 只是几种可能的 ReactNode 类型之一:

  • type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined
  • type ReactChild = ReactElement | ReactText

那么,为什么会出现这个错误? (undefined 不能分配给 ReactElement)?

错误意味着“一个孩子可能是 undefined 类型,但您传递给 map 的函数不会接受它。”

undefinedReactNode 定义和联合类型中的最后一个类型,这(显然)是 TypeScript 所做的 - 只抱怨最后一个不兼容的类型。