Home > Back-end >  Converting React files to Typescript
Converting React files to Typescript

Time:11-30

I am in the process of learning Typescript and am converting my React project to TS. However, I've hit a bit of a roadblock and I'm not quite sure what to do with this file:

import { Grid } from '@material-ui/core';
import { useParams } from 'react-router-dom';
// @ts-ignore
import ProductImage from './ProductImage.tsx';
// @ts-ignore
import ProductInfo from './ProductInfo.tsx';

type Props = {
  products: {
    id: number;
    price: number;
    description: string;
    listing_type: string;
    image: string;
  }[];
  addToCart: (e: MouseEvent) => void;
  user: {
    id: number;
    isAuth: boolean;
  };
}

const Product: React.FC<Props> = ({ products, addToCart, user }) => {
  const { productId } = useParams<{productId: string}>()

  const product = products.find(product => product.id === parseInt(productId));

  return (
    <div>
      <Grid container spacing={1} style={{ maxWidth: 1100, margin: '0 auto', marginTop: '5rem' }}>
        <Grid item sm={4}>
          <ProductImage image={product?.image} />
        </Grid>
        <Grid item sm={8}>
          <ProductInfo product={product} onClick={(e: React.MouseEvent<Element, globalThis.MouseEvent>) => addToCart(e)} user={user}/>
        </Grid>
      </Grid>
    </div>
  );
}

export default Product;

I added the @ts-ignore lines because of errors related to importing files ending with .tsx. However, now when I try to run npm start, I get the following error:

TypeError: products.find is not a function
Product
src/components/products/ProductShow.tsx:27
  24 | const Product: React.FC<Props> = ({ products, addToCart, user }) => {
  25 |   const { productId } = useParams<{productId: string}>()
  26 |   console.log(products)
> 27 |   const product = products.find(product => product.id === parseInt(productId));
  28 | 
  29 |   return (
  30 |     <div>

(I should note that products are passed down as an array of objects from a higher component)

At this point, I'm not sure if I'm defining my prop types incorrectly or if there is another issue with how I've set everything up. Any help with either configuring my project so that .tsx files can be imported or defining my prop types correctly would be greatly appreciated!

Here is my tsconfig.json file

{
  "compilerOptions": {
    "target": "es2016",
    "module": "esnext",
    "noImplicitAny": true,
    "esModuleInterop": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true,
    "strict": true,
    "jsx": "react-jsx",
    "allowJs": true,
    "checkJs": false,
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "include": [
    "src"
  ]
}

CodePudding user response:

The console log shared in the comments explains this issue. products is logging as:

{products: Array(20), loading: false}

.find() exists on Array.prototype, but is being called on an object. The prop products should be passed as the array of products, rather than an object.

  • Related