Проверяет умение расширять рекурсивный обход структуры данных для поддержки новых примитивных типов, таких как string, без нарушения существующей логики.
Когда вы пишете функцию, которая рекурсивно обходит структуру данных и проверяет типы значений, рано или поздно появляется необходимость поддержать новый примитивный тип, например string. Главная идея — не переписывать всю логику, а аккуратно добавить новую ветку проверки, сохранив существующее поведение для уже поддерживаемых типов.
Обычно такая функция выглядит как набор условий: сначала проверяем null, потом массивы, потом объекты, а затем примитивы. Новый тип добавляется именно на уровне примитивов.
function checkType(value) {
if (value === null) return 'null';
if (Array.isArray(value)) {
return value.map(checkType);
}
if (typeof value === 'object') {
const result = {};
for (const key in value) {
result[key] = checkType(value[key]);
}
return result;
}
if (typeof value === 'string') return 'string';
if (typeof value === 'number') return 'number';
if (typeof value === 'boolean') return 'boolean';
return 'unknown';
}
null проверяется первым, потому что typeof null === 'object'.Если завтра понадобится поддержать bigint или symbol, достаточно добавить ещё одну ветку if. Такой подход называется открытым для расширения и закрытым для изменения — принцип Open/Closed из SOLID.
В TypeScript можно пойти дальше и описать типы через discriminated union, тогда компилятор сам подскажет, какие ветки нужно обработать.
Итог: расширение проверки типов сводится к добавлению новой ветки в рекурсивную функцию, при этом важно сохранять порядок проверок и не забывать про вложенные структуры. Такой подход удобно применять в валидаторах, сериализаторах и системах миграции данных.
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию