如何确定nextjs子级是否为字符串

lxkprmvk  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(134)

在升级到下一个13代码之前,代码工作正常,现在我在vsode中得到这个typescript错误,buttonProps的类型是“ReactI18NextChild”类型|Iterable'.堆栈溢出说我必须添加更多的细节,因为我的帖子主要是代码。
“ReactI18NextChild”类型的参数|Iterable“不能赋给”ReactNode“类型的参数|[]“中定义。

import React, { ButtonHTMLAttributes } from 'react';
import { ReactI18NextChild } from 'react-i18next';
import { parseBackgroundColor, parseColor, parseBorderColor, parseFontSize } from 'styles/styles';

interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
    otherProps
}

function Button({ otherProps, ...buttonProps }: Props) {
    const isString = React.Children.toArray(buttonProps.children).some(child => {
      if (
        typeof child === 'string' ||
        typeof child === 'number' ||
        ((child as any)?.type && ['span', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes((child as any).type))
      ) {
        return true;
      }
    });

    return <button>{buttonProps.children}</button>
}

所有软件包均已更新为最新版本。

"dependencies": {
    "@aws-amplify/datastore": "^4.0.1",
    "@aws-sdk/util-credentials": "^3.56.0",
    "@capacitor/core": "^4.4.0",
    "@capacitor/device": "^4.0.1",
    "@react-pdf/renderer": "^3.0.1",
    "array-move": "^4.0.0",
    "aws-amplify": "5.0.1",
    "clsx": "^1.2.1",
    "crypto-js": "^4.1.1",
    "graphql-tag": "^2.12.6",
    "i18next": "^21.10.0",
    "i18next-locize-backend": "^6.0.0",
    "immer": "^9.0.16",
    "intl-tel-input": "^17.0.19",
    "ksuid": "^3.0.0",
    "locize-cli": "^7.12.8",
    "logrocket": "^3.0.1",
    "logrocket-react": "^5.0.1",
    "next": "^13.0.3",
    "next-pwa": "^5.6.0",
    "qrcode.react": "^3.1.0",
    "react": "18.2.0",
    "react-datepicker": "^4.7.0",
    "react-dnd": "^16.0.1",
    "react-dnd-html5-backend": "^16.0.1",
    "react-dom": "18.2.0",
    "react-google-charts": "^4.0.0",
    "react-i18next": "12.0.0",
    "react-indiana-drag-scroll": "^2.1.0",
    "react-loader-spinner": "^6.0.0-0",
    "react-query": "^3.39.2",
    "react-scripts": "5.0.1",
    "react-simple-keyboard": "^3.4.237",
    "sharp": "^0.31.2",
    "universal-cookie": "^4.0.4",
    "zustand": "^4.1.4"   },   "devDependencies": {
    "@babel/helper-call-delegate": "^7.12.1",
    "@types/crypto-js": "^4.0.2",
    "@types/intl-tel-input": "^17.0.6",
    "@types/logrocket-react": "^3.0.0",
    "@types/node": "18.11.9",
    "@types/qrcode.react": "^1.0.1",
    "@types/react": "^18.0.25",
    "@types/react-datepicker": "^4.8.0",
    "@types/react-dom": "^18.0.9",
    "@typescript-eslint/eslint-plugin": "5.43.0",
    "@welldone-software/why-did-you-render": "^7.0.1",
    "autoprefixer": "^10.4.13",
    "eslint": "8.27.0",
    "eslint-config-next": "13.0.3",
    "eslint-config-prettier": "^8.5.0",
    "husky": "^8.0.2",
    "lint-staged": "^13.0.3",
    "postcss": "^8.4.19",
    "prettier": "^2.6.1",
    "stylelint": "^14.15.0",
    "stylelint-config-prettier": "^9.0.4",
    "stylelint-config-standard": "^29.0.0",
    "stylelint-config-tailwindcss": "^0.0.7",
    "tailwindcss": "^3.2.4",
    "typescript": "4.9.3"   } }
2vuwiymt

2vuwiymt1#

此错误的原因是react-i18next的类型定义。react-i18next类型定义文件中存在某些interface扩充,这些扩充会重写现有类型。
问题在于:

type ObjectOrNever = TypeOptions['allowObjectInHTMLChildren'] extends true
  ? Record<string, unknown>
  : never;
type ReactI18NextChild = React.ReactNode | ObjectOrNever;

declare module 'react' {
  interface HTMLAttributes<T> {
    children?: ReactI18NextChild | Iterable<ReactI18NextChild>;
  }
}

由于某种原因,children被覆盖为ReactI18NextChild | Iterable<ReactI18NextChild>类型。并且ReactI18NextChild将此ObjectOrNever类型包括在具有可能的Record<string, unknown>输出类型的联合中。并且Record<string, unknown>无法分配给React.ReactNode,从而导致错误。
我个人建议现在只使用类型Assert:

const isString = React.Children.toArray(
  buttonProps.children as React.ReactNode
).some(child => {
  /* ... */
});

或者完全删除react-i18next导入(如果可能)。
无论哪种方式,你都可以在Github上打开一个关于这个问题的问题。这可能是也可能不是缩进的行为,特别是如果在更新之前这是有效的。

相关问题