Как получить доступ к свойству объекта с помощью динамического ключа в Typescript?

#javascript #typescript #object

Вопрос:

В моем компоненте Product.tsx я получаю объект через вызов API, который может выглядеть следующим образом:

 {
  title: "Product 1",
  status: "active",
  tax: true,
  variants: [
    {
      id: 1,
      sku: 'PRD1',
      price: 24.00,
      price_reduced: 19.95,
      size: 'M'
    },
    {
      id: 2,
      sku: 'PRD2',
      price: 24.00,
      price_reduced: 19.95
      size: 'L'
    },
  ]
}
 

Затем я визуализирую каждую variant строку в таблице, где в каждом столбце Отображается цена, размер и т. Д. В виде редактируемых полей ввода. onChange каждого input триггера updateVariant(variant.id, key, e); , где key является одним из ключей a variant и e является входным событием.

updateVariant следует обновить значение a variant с учетом приведенного key и выглядит так:

   const updateVariant = (
    id: number,
    key: string,
    e: React.FormEvent<HTMLInputElement>
  ) => {
    setProduct((prevState) => {
      const update = { ...prevState };
      const i = update.variants.findIndex((variant) => variant.id === id);
      const updatedVariant = update.variants[i];
      updatedVariant[key] = e.currentTarget.value;   // errors on this line
      update.variants[i] = udpatedVariant;
      return update;
    });
  };
 

Это дает мне ошибку на updatedVariant[key] = e.currentTarget.value; :

 Element implicitly has 'any' type because expression of type 'string | number' can't be
used to index type '{id: number, sku: string, ...}'. No index signature with a parameter
of type 'string' was found on type '{id: number, sku: string ...}'
 

Я попытался изменить его на:
updatedVariant[key as keyof typeof updatedVariant] = e.currentTarget.value;
что приводит меня к ошибке type 'any' is not assignable to type 'never'

Я совсем новичок в машинописи и совершенно не понимаю, как это работает.

РЕДАКТИРОВАТЬ: я заставил его временно работать с

 updatedVariant[key as keyof typeof updatedVariant] = e.currentTarget.value as never;
 

Но это не может быть правильным / чистым решением для этого?

Комментарии:

1. пробовать updatedVariant[key] = e.currentTarget.value as number | string;

Ответ №1:

Я заставил это работать, объявив интерфейс таким образом:

 interface Variant {
  [key: string]: string | number | string[];
}
 

и затем

 (updatedVariant as Variant)[key] = e.currentTarget.value;
 

Моя ошибка заключалась в том, что я думал, что key в этом отсутствует тип или что-то в этом роде, когда на самом деле мне нужен был интерфейс для updatedVariant .