I'm trying to reduce my code and render a series of MUI rows through a loop and Object.entries
. Though each time that I try to extract the value of a sperate Object, I get
TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Chalk'. No index signature with a parameter of type 'string' was found on type 'Chalk'.
rowLabels and chalk keys match.
const ConfigureRowValue = () => {
const rowLabels = {
sling: 'Load',
bump: 'Bump Priority',
equipment: 'Key Equipment',
w: 'Key W',
notes: 'Notes',
};
for (const [key, value] of Object.entries(rowLabels)) {
return (
<>
<ChalkCardDataRow
label={`${value}`}
value={`${chalk[key]}`}
/>
</>
);
}
};
*****************************************
type ChalkCardDataRowProps = {
label: string;
value: string | null;
};
export const ChalkCardDataRow = ({ label, value }: ChalkCardDataRowProps) => {
return (
<TableRow>
<TableCell style={{ borderBottom: 'none' }}>{label}:</TableCell>
<TableCell
align={'right'}
style={{ borderBottom: 'none' }}
>
<Typography color='grey'>{value ?? '-'}</Typography>
</TableCell>
</TableRow>
);
};
If I explicitly insert the component multiple times it works but causes too much code duplication. i.e:
<ChalkCardDataRow
label={'Sling Load'}
value={chalk.sling}
/>
<ChalkCardDataRow
label={'Bump Priority'}
value={chalk.bump}
/>
CodePudding user response:
Unfortunately Object.entries
return type gives the keys as string
, instead of keyof object
. See ms/TS#12253 for explanations on this design choice.
The usual workaround is to use a type assertion in this case, since you are sure that both objects have the same keys: chalk[key as keyof typeof rowLabels]
Another solution would be to use ts-extras/objectEntries
:
A strongly-typed version of
Object.entries()
.
import {objectEntries} from 'ts-extras';
for (const [key, value] of objectEntries(rowLabels)) {
result.push(
<>
<ChalkCardDataRow
label={`${value}`}
value={`${chalk[key]}`} // Okay
/>
</>
);
}