Home > database >  Element implicitly has an 'any' type because expression of type 'any' can't
Element implicitly has an 'any' type because expression of type 'any' can't

Time:10-21

I am trying to build a route with node and typescript where I can add products to a cart, however it is complaining about the interface.

Here is the interface in interfaces.ts:

import { Document } from "mongoose";
export interface IUser extends Document {
  firstName: string;
  lastName: string;
  email: string;
  password: string;
  cart: ICart;
  orders: IOrders[];
}

export interface ICart {
  total: number;
  count: number;
}

My model in UserModel.ts:

const UserSchema = new Schema({
  firstName: {
    type: String,
    required: true,
  },
  lastName: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
    validate: {
      validator: function (str: string) {
        return /^[\w-\.] @([\w-] \.) [\w-]{2,4}$/g.test(str);
      },
      message: (props: { value: string }) =>
        `${props.value} is not a valid email`,
    },
  },
  password: {
    type: String,
    required: true,
  },

  cart: {
    type: Object,
    default: {
      total: 0,
      count: 0,
    },
  },
  orders: [{ type: mongoose.Schema.Types.ObjectId, ref: "Order" }],
});

const UserModel = mongoose.model<IUser>("User", UserSchema);

export default UserModel;

And lastly, the route in productRoutes.ts:

productRoutes.post('/add-to-cart', async(req, res)=> {
    const {userId, productId, price} = req.body;
    try {
      const user = await UserModel.findById(userId);
      const userCart = user.cart;
      if(user.cart[productId]){
        userCart[productId]  = 1;
      } else {
        userCart[productId] = 1;
      }
      userCart.count  = 1;
      userCart.total = Number(userCart.total)   Number(price);
      if (user) {
        user.cart = userCart;
        user.markModified('cart');
        await user.save();
      }
      res.status(200).json(user);
    } catch (e) {
      res.status(400).send(e);
    }
  })

The error I am getting is in productRoutes.ts, in my try catch, specifically in these two parts:

const userCart = user.cart; // Object is possibly 'null'
      if(user.cart[productId]){ // Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'ICart'.
        userCart[productId]  = 1; // Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'ICart'.
      } else {
        userCart[productId] = 1; // Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'ICart'.
      }

What am I doing wrong, where do I type it and how do I index type "ICart"?

CodePudding user response:

Try this syntax:

const userCart = user.cart!;

CodePudding user response:

First error

const userCart = user.cart; // Object is possibly 'null'

TypeScript (rightfully) warns you that the user object can be null (which would happen if the document is not found in the user collection).

Instead of muting the error with the non-null assertion operator !, I suggest you make sure the document exists indeed:

  const { userId, productId, price } = req.body;

  const user = await UserModel.findById(userId);
  if (!user) {
    res.status(400).send("User not found");

    return;
  }

  const userCart = user.cart; // no TS errors

Second error

if(user.cart[productId]){ // Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'ICart'.

First, you want to properly type the request body, to let the compiler know the data type of productId.

interface IAddToCartRequestBody {
  userId: string;
  productId: string;
  price: number;
}

productRoutes.post('/add-to-cart', async (req: express.Request<any, any, IAddToCartRequestBody>, res) => {
  const { userId, productId, price } = req.body;

  ...

Second, allow product IDs as keys

export interface ICart {
  [productId: string]: number;
  total: number;
  count: number;
}

These updates combined should resolve all of the TypeScript errors (in strict mode).

  • Related