如何在TypeScript中以类型安全的方式访问React子元素的属性?

3

我正在尝试访问 React [Native] 组件中的 props。这些组件保证是我自定义类型 ItemTemplate 的元素实例:

const children = React.Children.toArray(this.props.children);
return children.find(t => t.props.itemKey == key);

然而,在第二行当我尝试访问t.props时,我得到:

Property 'props' does not exist on type 'ReactElement<ItemTemplate, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | ... 13 more ... | (ReactElement<...>[] & ReactPortal)'.
  Property 'props' does not exist on type 'ReactElement<ItemTemplate, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>[] & string'.

代码可以正常工作,但是 TypeScript (3.6.3) IntelliSense 发出了警告。为什么?

1
谁给踩了赞,能不能至少解释一下原因? - Can Poyrazoğlu
2个回答

2
在这种情况下,您需要声明或将子元素转换为ReactElement。这里有一个来自nextjs的Link组件到自定义NavLink的示例:
import { ReactElement, cloneElement } from 'react';
import Link, { LinkProps } from 'next/link';

type NavigationData = {
    currentPath: string;
    pathsToMatch: string[] | string;
    activeClassName: string;
    children: ReactElement;
};

type NavLinkProps = LinkProps & NavigationData;

export default function NavLink({
    currentPath,
    pathsToMatch,
    activeClassName,
    children,
    ...props
}: NavLinkProps): ReactElement {
    function GetActiveLink(
        currentPath: string,
        paths: string | string[],
        activeClassName: string
    ): string {
        if (currentPath === '/' && paths === '/') {
            return activeClassName;
        } else if (currentPath !== '/' && paths.indexOf(currentPath) !== -1) 
        {
            return activeClassName;
        }

        return '';
    }

   let className: string = children.props.className || '';
   className += ` ${GetActiveLink(currentPath, pathsToMatch, activeClassName)}`;

    return <Link {...props}>{cloneElement(children, { className })}</Link>;
}

通过这种方式,您可以访问属性prop而不会收到任何警告。
愉快的编码。 :-)

0

使用方法如下:

const children: Array<ReactChild> = React.Children.toArray(this.props.children);
return children.find(t => t.props.itemKey == key);

或者使用您自定义的类型 ItemTemplate:

const children: Array<ItemTemplate> = React.Children.toArray(this.props.children);
return children.find(t => t.props.itemKey == key);

它不起作用。它无法将该类型分配给“children”:... 类型'ReactElement<ItemTemplate,string | ((props: any) => ReactElement<any,string | ... | (new(props: any) => Component<any,any,any>)> | null) | (new(props: any) => Component<any,any,any>)>'缺少以下属性:render、context、setState、forceUpdate和2个更多.ts(2322) - Can Poyrazoğlu
尝试使用以下代码: const children: any = React.Children.toArray(this.props.children); return children.find(t => t.props.itemKey == key); - Prabhunath Yadav
除了将 JavaScript 迁移到 TypeScript 时,不应使用 any - Steve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接