【问题标题】:Binding element 'x' implicitly has an 'any' type绑定元素“x”隐式具有“任何”类型
【发布时间】:2022-02-03 17:08:05
【问题描述】:

我一直致力于通过使用教程文章 (https://www.mikealche.com/software-development/learn-react-animations-by-creating-a-stripe-inspired-menu) 构建导航栏来学习和理解 Nextjs 和 TypeScript。

尽管菜单项似乎在本地工作并且下划线动画进入并跟随鼠标悬停(这是我在文章中得到的),但我仍然遇到以下问题:

  1. 菜单项.tsx
    • 绑定元素“text”隐含地具有“any”类型。 ts(7031) [6,21]
    • 绑定元素“children”隐含地具有“any”类型。 ts(7031) [6,27]
  2. 子项.tsx
    • 参数“title”隐含地具有“any”类型。 ts(7006) [4,18]
    • 参数“text”隐含地具有“any”类型。 ts(7006) [4, 25]
  3. SubItemContainer.tsx
    • 绑定元素“children”隐含地具有“any”类型。 ts(7031) [3,29]

我对 React、NextJs 和 TypeScript 还是很陌生,但我已经慢慢地阅读了文档、视频,并且耐心地学习。但是我不太确定如何解决这个问题,或者找到一种方法来更好地缓解这种情况在未来发生。

我已经继续并发布了以下文件。

感谢您对此提供的任何帮助或建议。

Navbar.tsx

import React from "react";
import MenuItem from "./MenuItem";
import SubItem from "./SubItem";
import { motion } from "framer-motion";

const Navbar = () => {
  return (
    <div className="w-screen p-20">
      <motion.div className="flex justify-center p-10 border">
        <MenuItem text={"Home"}>
          <SubItem title="Product" text="A SaaS for e-commerce" />
          <SubItem title="Blog" text="Latest posts" />
          <SubItem title="Contact" text="Get in touch" />
        </MenuItem>
        <MenuItem text={"About"} style={{ minWidth: 400 }}>
          <SubItem title="The Team" text="Get to know us better" />
          <SubItem title="The Company" text="Since 1998" />
          <SubItem
            title="Our Mission"
            text="Increase the GDP of the internet"
          />
          <SubItem title="Investors" text="who's backing us" />
        </MenuItem>
        <MenuItem text={"Products"} style={{ minWidth: 400 }}>
          <SubItem
            title="Ecommerce"
            text="Unify online and in-person payments"
          />
          <SubItem
            title="Marketplaces"
            text="Pay out globally and facilitate multiparty payments"
          />
          <SubItem
            title="Platforms"
            text="Let customers accept payments within your platform"
          />
          <SubItem
            title="Creator Economy"
            text="Facilitate on-platform payments and pay creators globally"
          />
        </MenuItem>
      </motion.div>
    </div>
  );
};

export default Navbar;

MenuItem.tsx

import { motion } from "framer-motion";
import { useState } from "react";
import Underline from "./Underline";
import SubItemContainer from "./SubItemContainer";

const MenuItem = ({ text, children, ...props }) => {
  const [isBeingHovered, setIsBeingHovered] = useState(false);

  return (
    <motion.div
      className="relative px-10 cursor-pointer"
      onHoverStart={() => setIsBeingHovered(true)}
      onHoverEnd={() => setIsBeingHovered(false)}
    >
      <span className="relative">
        {text}
        {isBeingHovered && <Underline />}
      </span>
      {isBeingHovered && <SubItemContainer>{children}</SubItemContainer>}
    </motion.div>
  );
};

export default MenuItem;

SubItem.tsx

import { Hashicon } from "@emeraldpay/hashicon-react";
import React from "react";

const SubItem = (title, text) => {
  return (
    <div className="my-2 cursor-pointer group min-w-max">
      <div className="flex items-center gap-4">
        <Hashicon value={title} size={25} />
        <div className="">
          <p className="font-bold text-gray-800 group-hover:text-blue-900 text-md">
            {title}
          </p>
          <span className="text-sm font-bold text-gray-400 group-hover:text-blue-400">
            {text}
          </span>
        </div>
      </div>
    </div>
  );
};

export default SubItem;

SubItemContainer.tsx

import { motion } from "framer-motion";

const SubItemContainer = ({ children }) => {
  return (
    <div className="py-5 min-w-max">
      <motion.div
        layoutId="menu"
        className="absolute border border-1 shadow-lg py-10 px-10 bg-white rounded-box -left-2/4"
        style={{ minWidth: 400 }}
        initial="hiddens"
        animate="visible"
      >
        {children}
      </motion.div>
    </div>
  );
};

export default SubItemContainer;

【问题讨论】:

    标签: javascript reactjs typescript next.js


    【解决方案1】:

    虽然 typescript 在大多数情况下都能够推断类型,但它不能用于 react 道具,即使是儿童道具。

    要删除代码中的所有XXX implicitly has an 'any' type,您需要在使用自己的道具时使用childrenReact.FC&lt;ComponentProps&gt; 为您的组件添加React.FC(代表功能组件)。

    对于您当前的三个组件,您将拥有:

    MenuItem.tsx

    [...]
    
    // Define your component props
    type MenuItemProps = {
      text: string;
      // ...rest of your props
    }
    
    // Add props
    const MenuItem: React.FC<MenuItemProps> = ({ text, children, ...props }) => {
    
    [...]
    

    SubItem.tsx

    [...]
    
    // Define your component props
    type SubItemProps = {
      title: string;
      text: string;
    }
    
    // Add props and fix your code as props is the first parameter
    const SubItem: React.FC<SubItemProps> = ({ title, text }) => {
    
    [...]
    

    SubItemContainer.tsx

    [...]
    
    // Only add React.FC 
    const SubItemContainer: React.FC = ({ children }) => { type
    
    [...]
    

    【讨论】:

    • 谢谢 P.E.在解决了最初的问题后,我现在遇到了几个新错误。 Navbar.tsx 类型'{孩子:元素[];文本:字符串;样式:{ minWidth:数字; }; }' 不可分配给类型 'IntrinsicAttributes & IMenuItem & { children?: ReactNode; }'。类型'IntrinsicAttributes & IMenuItem & { children?: ReactNode; 上不存在属性'style' }'。 SubMenuItem.tsx(以前的 SubItem.tsx) 没有重载匹配此调用。 ts(2769) [9, 19]
    • 我把“// ...rest of your props”放在哪里,你应该添加你在传播道具时所期望的缺失的道具。似乎缺少style?: CSSProperties | undefined。你需要从 react 中导入 CSSProperties。
    • 再次感谢 - 我完全错过了那部分,并且能够解决样式问题。
    • 非常肯定,Tailwind 不会以任何方式影响您的类型定义。不过,如果您需要将类名发送到组件,请记住将 className: string; 添加到其 props 类型。如果您因为 Tailwind 而遇到任何打字稿问题,我很想知道:链接您在此线程中提出的任何 StackOverflow 问题,我会检查它们。
    猜你喜欢
    • 1970-01-01
    • 2021-10-04
    • 2017-04-06
    • 1970-01-01
    • 2019-12-13
    • 2021-05-15
    • 2020-06-19
    • 2023-01-28
    • 2021-08-26
    相关资源
    最近更新 更多