Вопрос или проблема
Итак, я смотрю на этот кусок кода, который, похоже, никогда не работал. Он в основном находит путь в json и обновляет его значения.
Он использует lodash, и когда я углубился в это, тип, который он ожидает, выглядит так:
type PropertyPath = Many<PropertyName>;
/** Общий интерфейс между массивами и объектами jQuery */
Этот кусок кода использует этот тип следующим образом:
import { PropertyPath, set } from 'lodash';
export async function setConfig(
service: string,
path: PropertyPath,
value: number | boolean | string
) {
const config: Record<string, unknown> = await getConfig(
SERVICES[service]
);
set(config, path, value);
...// больше кода для обновления конфигурации, но проблема в вышеупомянутом
})
Так что в коде, который вызывает этот метод, это выглядит так:
const epic = [‘epic’, ‘reprint’, ‘enabled’];
await setConfig('gaming', epic, true);
Итак, исходя из этого примера, мы надеемся, что в сервисе gaming мы можем изменить флаг, находящийся по этому json пути epic.reprint.enabled
, чтобы он был установлен на true.
Однако я замечаю, что он никогда не изменял флаг. У меня есть обходной способ, который не использует тип пути свойства для обновления флагов, но так как этот код используется во многих местах, я надеялся, что кто-то подскажет, как правильно передать значения пути для этого типа PropertyPath, чтобы мы могли обновить флаги таким образом.
Ответ или решение
Ваша проблема заключается в том, что PropertyPath
в библиотеке Lodash ожидает путь к свойствам объекта, который может быть представлен как массив строк или строковых литералов. Однако, в случае вложенных свойств, особенно когда дело касается массивов, необходимо учитывать не только ключи объекта, но и индексы массива.
Давайте рассмотрим ваш код и проблему более детально. У вас есть следующая структура JSON:
{
"epic": {
"reprint": {
"enabled": false
}
}
}
При работе с массивами и объектами в Lodash, путь к значению, которое вы хотите изменить, должен быть правильно сформирован. Ваша текущая попытка передать массив ['epic', 'reprint', 'enabled']
как путь является правильной, и следующий код должен работать, если исходный объект имеет правильную структуру.
Однако, если у вас возникают проблемы с обновлением значения с использованием set
, стоит проверить несколько моментов:
-
Структура исходного объекта: Убедитесь, что объект, возвращаемый функцией
getConfig
, действительно содержит нужную структуру. Вы можете временно добавить логирование, чтобы посмотреть, что именно получаете:const config: Record<string, unknown> = await getConfig(SERVICES[service]); console.log(config); // Добавьте это для отладки
-
Правильное использование метода
set
: Методset
должен работать, если путь указан правильно. Например:import { set } from 'lodash'; const path = ['epic', 'reprint', 'enabled']; const value = true; set(config, path, value);
-
Проверка изменений: После вызова метода
set
, убедитесь, что вы правильно проверяете обновление значения. Это может включать дополнительное логирование, чтобы подтвердить, что изменения действительно происходят.
Если ваш объект имеет массивы, вы должны указывать индекс в массиве. Например, если структура вашего epic
была такой:
{
"epic": [
{
"reprint": {
"enabled": false
}
}
]
}
В этом случае путь к свойству enabled
будет выглядеть так: ['epic', 0, 'reprint', 'enabled']
.
Вот полное обновление функции setConfig
с добавленным логированием:
import { PropertyPath, set } from 'lodash';
export async function setConfig(
service: string,
path: PropertyPath,
value: number | boolean | string
) {
const config: Record<string, unknown> = await getConfig(SERVICES[service]);
console.log("Исходная конфигурация:", config);
set(config, path, value);
console.log(`Обновленная конфигурация по пути ${path.join('.')} установлена на:`, value);
}
Если после проверки всех вышеуказанных моментов проблема всё еще сохраняется, возможно, вам стоит убедиться, что изменения действительно сохраняются вне данного контекста. Вы можете захотеть включить логику сохранения обновленного config
обратно в систему после изменения его значений.
Надеюсь, это поможет вам решить вашу проблему с использованием PropertyPath
в TypeScript и успешно использовать Lodash для обновления значений в JSON-объекте!