React.Children.toArray 无法使用打字稿找到儿童的道具

Spe*_*gum 4 typescript reactjs

打字稿无法使用 React.Children.toArray 检测儿童上的道具对象我必须使用 any[] 因为如果我使用 ReactChild[] - 在数组项上未检测到道具。我如何正确输入这个?谢谢!

const items: any[] = React.Children.toArray(this.props.children)

// select whatever item was told to be onload first
const itemPaymentType = items[0].props['data-payment']
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

Uzi*_*Uzi 11

casieber 的答案是正确的。

但是为了使用打字稿访问你的道具,这是必要的:

const item = items[0];
if (React.isValidElement<{prop1: boolean}>(item)) {

    // item.props.prop1 -- works
}
Run Code Online (Sandbox Code Playgroud)


cas*_*ber 7

Typescript 在这里做的是正确的事情。看一下 ReactChild 的类型定义:

type ReactChild = ReactElement<any> | ReactText;
Run Code Online (Sandbox Code Playgroud)

whereReactText输入为string | number.

通过说const items: ReactChild[]你告诉 TypeScript 这items是一个包含可能是字符串元素的数组。显然,字符串没有props作为属性,因此当您尝试使用props.

如果您确信您的组件的孩子将永远只能是包含你正在寻找的道具类型的真实元素,那么你可以输入输出ReactElement<P>这里P是你所期望的道具类型。但是,这样做本质上是在投射一些您无法保证的东西。更好的方法可能是允许 TypeScript 类型推断通过如下方式发挥作用:

const items = React.Children.toArray(this.props.children); // Will be ReactChild[]

const item = items[0];
if (typeof item === 'string' || typeof item === 'number') {
    console.error('Expecting component children to be of type ...');
} else {
    // At this point, TypeScript will know that item must be of type ReactElement
    // since you have already taken care of the number and string case
    const itemPaymentType = item.props['data-payment'];
    // ...
}
Run Code Online (Sandbox Code Playgroud)