Home > Back-end >  TypeScript Error: Element implicitly has an 'any' type because expression of type 'st
TypeScript Error: Element implicitly has an 'any' type because expression of type 'st

Time:08-22

My code is just warning fine, but I'm facing an Error type from Ts while accessing an element in the object using string.

    useEffect(() => {
    const categoriesResult: CategoryResult[] = Object.values(
      questions?.reduce((r, e) => {
        const k = e.category.id;
        if (!r[k as keyof object])
          return r[k].totalCount  = 1;
      }, {})
    );
    setCategories(categoriesResult);
  }, [questions]);

The error is in r[k] to be more specific.

Thanks

CodePudding user response:

There is a lot going on here so I will unpack this line by line.

First, let's ignore useEffect.

Next, the assignment:

const categoriesResult: CategoryResult[] = Object.values(

This looks fine Object.values will return an array, and you expect those to be CategoryResult type.

Ok, let's tackle the entire reduce block:

questions?.reduce((r, e) => {
  const k = e.category.id;
  if (!r[k as keyof object])
    return r[k].totalCount  = 1;
}, {})

Your array of questions is to be reduced to an object {}.

First issue, you need to return r always, so let's make the code this:

questions?.reduce((r, e) => {
  const k = e.category.id;
  if (!r[k as keyof object]) {
    r[k].totalCount  = 1;
  }
  return r
},{})

Without returning r you will not reduce, you will have an empty object.

Next, r, starts it's life being equal to {} - an object - hence the error - string can't be used to index type {}

There is some valid code below for what you are trying to achieve, in this code, the type of {} is set explicitly so that it knows the object has string keys, and values of CategoryResult types:

// The result type
type CategoryResult = {
  totalCount: number;
};

// Some example questions
const questions = [
  {
    category: {
      id: "How should this work?",
    },
  },
  {
    category: {
      id: "Does that make sense?",
    },
  },
  {
    category: {
      id: "Does that make sense?",
    },
  },
];

// A count on questions
const questionCounts = questions?.reduce(
  (r, e) => {
    const k = e.category.id;

    if (r[k] === undefined) {
      r[k] = {
        totalCount: 1,
      };
    } else {
      r[k].totalCount  = 1;
    }

    return r;
  },
  // The type of the questions count accumulator in the reduce
  {} as Record<string, CategoryResult>
);

const categoriesResult: CategoryResult[] = Object.values(questionCounts);

console.info("result", { categoriesResult });
  • Related