Я получаю параметры поля выбора, перебираю метки, группу опций и значения в поле выбора. Что-то не так с тем, как я создал свои типы?
interface Option {
label: string
value: string
selected?:boolean
mainGroup?: string
optgroup?: "" | string | [] | undefined
}
const trackNames: Option[] = [
{
value: "Track1",
label: "Track One",
optgroup: "",
},
{
value: "Track2",
label: "Track Two",
optgroup: "",
},
{
value: "Track3",
label: "Track Three",
optgroup: "Track3-Group",
},
{
value: "Track4",
label: "Track Four",
optgroup: "Track3-Group",
}
];
// код sample.js
import { trackNames as trackNameData } from '/helper/Data'
const groupedOptions = {};
trackNameData.forEach((option: { optgroup: any; value: any; label: any }) => {
if (!groupedOptions[option.optgroup]) groupedOptions[option.optgroup] = [];
groupedOptions[option.optgroup].push({
value: option.value,
label: option.label,
});
});
const renderOptions = (options: any[]) => {
return options.map((option) => {
return (
<option key = {option.value} value = {option.value}>
{option.label}
</option>
);
});
};
<select>
<option value=''>Please select</option>
{Object.keys(groupedOptions).map((group, index) => {
return (
<optgroup key = {index} label = {group}>
{renderOptions(groupedOptions[group])}
</optgroup>
);
})}
</select>
Когда я импортирую trackData в другой файл JS для отображения параметров в поле выбора, я получил ошибку ниже:
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}'.ts(7053)
Что я делаю не так? Я рассмотрел другие решения и не могу заставить их работать.
🤔 А знаете ли вы, что...
JavaScript поддерживает работу с различными форматами данных, такими как JSON и XML.
Если вы собираетесь индексировать groupedOptions
с каким-то произвольным ключом, то вам нужно присвоить ему тип с сигнатурой индекса . Из вашего примера кода я ожидаю, что вы хотите, чтобы значения были массивами Options
. Таким образом, тип {[k: string]: Option[]}
или его эквивалент Record<string, Option[]>
(с использованием типа утилиты Record) будет работать:
const groupedOptions: Record<string, Option[]> = {};
Как только вы это сделаете, запись groupedOptions[xxx]
не будет ошибкой, если xxx
похож на ключ:
trackNames.forEach((option: { optgroup?: any; value: any; label: any }) => {
if (!groupedOptions[option.optgroup]) groupedOptions[option.optgroup] = [];
groupedOptions[option.optgroup].push({
value: option.value,
label: option.label,
});
});
Теперь это компилируется так, как написано, без ошибок. Но обратите внимание, что вы указали optgroup
намеренно потерять любой тип , что в большинстве случаев отключает проверку типов. Вообще говоря, вам следует индексировать только объекты с string
, number
или symbol
. Если optgroup
действительно может быть undefined
или пустым массивом []
(обратите внимание, что []
— это тип кортежа с нулевыми элементами, а не произвольный тип массива), то индексация объекта с его помощью будет иметь неожиданные результаты. Я считаю, что это выходит за рамки заданного вопроса, но вам действительно следует убедиться, что ключи вашего объекта действительны.
Детская площадка, ссылка на код
interface Option {
label: string
value: string
selected?:boolean
mainGroup?: string
optgroup?: "" | string | [] | undefined
}
const trackNames = [
{
value: "Track1",
label: "Track One",
optgroup: "",
},
{
value: "Track2",
label: "Track Two",
optgroup: "",
},
{
value: "Track3",
label: "Track Three",
optgroup: "Track3-Group",
},
{
value: "Track4",
label: "Track Four",
optgroup: "Track3-Group",
}
] as const satisfies Option[];
const groupedOptions: { [key in typeof trackNames[number]['optgroup']]: { value: string, label: string }[] } = {} as any;
trackNames.forEach((option) => {
if (!groupedOptions[option.optgroup]) groupedOptions[option.optgroup] = [];
groupedOptions[option.optgroup].push({
value: option.value,
label: option.label,
});
});