I've been working on trying to learn and understand Nextjs and TypeScript by trying to build a Navbar by using a tutorial article (https://www.mikealche.com/software-development/learn-react-animations-by-creating-a-stripe-inspired-menu).
Despite the fact the menu items seem to be working locally and the underline animation comes in and follow the mouse hover (this is as far as I've gotten in the article) I am still getting the following problems:
- MenuItem.tsx
- Binding element 'text' implicitly has an 'any' type. ts(7031) [6,21]
- Binding element 'children' implicitly has an 'any' type. ts(7031) [6,27]
- SubItem.tsx
- Parameter 'title' implicitly has an 'any' type. ts(7006) [4,18]
- Parameter 'text' implicitly has an 'any' type. ts(7006) [4, 25]
- SubItemContainer.tsx
- Binding element 'children' implicitly has an 'any' type. ts(7031) [3,29]
I'm still pretty new with React, NextJs and TypeScript but have slowly been going through the docs, the vids, and having patience in learning. However I am not too sure how to fix this, or find a way to better mitigate this from happening in the future.
I've gone ahead and posted the files below.
Thanks for any help on this or suggestions.
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;
CodePudding user response:
While typescript is able to infer types most of the time, it cannot do it for react props, even for children props.
To remove all the XXX implicitly has an 'any' type in your code, you need to add a React.FC (stands for Functional Component) for your components using children and React.FC<ComponentProps> when using your own props.
For your three current component you would have:
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
[...]
