在child.type.nameReact typescript 中访问www.example.com

dnph8jn4  于 2022-12-19  发布在  TypeScript
关注(0)|答案(3)|浏览(120)

我在整个Typescript应用程序中使用React Functional组件。
我正在尝试动态更新另一个组件中的一些子组件,如下所示:

const memoizedIterateAndAddProps = useCallback(
    (kids: ReactNode) => {
      return React.Children.map(kids, (child) => {
        if (React.isValidElement(child)){
           console.log(child.type.name)
          }
      }
  }, [])

但是 typescript 一直抱怨Property 'name' does not exist on type 'string | JSXElementConstructor<any>'. Property 'name' does not exist on type 'string'.ts(2339)
我知道这与一个孩子可能只是一个字符串的事实有关,但我找不到一种方法来解决这个问题,使Typescript高兴。
我会非常感激任何人的帮助

ccrfmcuu

ccrfmcuu1#

......但我想不出一个能让Typescript满意的解决方法。
检查它是否为字符串:

const memoizedIterateAndAddProps = useCallback(
    (kids: ReactNode) => {
        return React.Children.map(kids, (child) => {
            if (React.isValidElement(child) && typeof child.type !== "string") {
//                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
               console.log(child.type.name);
            }
        });
    }
);

(Or && "name" in child.type也可以。)
在执行<div/>等操作时,会得到type的字符串,因此如果要使用name,必须过滤掉这种情况。

thtygnil

thtygnil2#

React.isValidElement具有以下类型签名:

function isValidElement<P>(object: {} | null | undefined): object is ReactElement<P>;

在typeguard之上,将child缩小为ReactElement,其具有以下类型签名:

interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
        type: T;
        props: P;
        key: Key | null;
    }

您可能已经注意到,typestringJSXElementConstructor<any>的并集。
因此,如果你想确保你有一个处理函数,你应该使用自定义typeguard:

const isFunction=(data:any):data is (...args:any[])=>any => typeof data === 'function'

完整代码:

import React, { useCallback, ReactNode } from 'react'
const isFunction = (data: any): data is (...args: any[]) => any => typeof data === 'function'

const App = () => {
  const memoizedIterateAndAddProps = useCallback(
    (kids: ReactNode) => {
      return React.Children.map(kids, (child) => {
        if (React.isValidElement(child) && isFunction(child.type)) {
          console.log(child.type.name)
        }
      }
  }, [])

  return null
}

Playground

nhjlsmyf

nhjlsmyf3#

import { isValidElement } from 'react'

if (isValidElement(child) && typeof child.type === 'function') {
  console.log(child.type.name) // safe access to name
}

检查:

  • childReactElement,且React元素具有type性质。
  • typefunction,并且函数具有name属性。

相关问题