In my component Product.tsx
I receive an object via API call that could look like this:
{ 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' }, ] }
I then render each variant
as a row in a table where each column displays the price, size etc. as editable input fields. onChange
of each input
triggers updateVariant(variant.id, key, e);
where key
is one of the keys of a variant
and e
is the input event.
updateVariant
should update the value of a variant
with the given key
and looks like this:
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; }); };
It gives me an error on 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 ...}'
I tried changing it to:
updatedVariant[key as keyof typeof updatedVariant] = e.currentTarget.value;
which gives me the error type 'any' is not assignable to type 'never'
I am quite new to Typescript and completely lost how to make this work.
EDIT: I got it to work temporarily with
updatedVariant[key as keyof typeof updatedVariant] = e.currentTarget.value as never;
But this can’t be the right / clean solution to this?
Advertisement
Answer
I got it working by declaring an interface like so:
interface Variant { [key: string]: string | number | string[]; }
and then
(updatedVariant as Variant)[key] = e.currentTarget.value;
My mistake was to think that key
was missing a type or something when in fact I needed an interface for updatedVariant
.