简体   繁体   中英

TypeScript Error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'

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

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 });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM