Используйте generic-типы объекта, ключа и значения. Для известного литерального ключа возвращаемый тип должен исключать старое поле и добавлять новое, иначе перезапись может дать несовместимое пересечение.
Обеспечение типовой безопасности функции добавления свойства
Используйте generic-типы объекта, ключа и значения. Для известного литерального ключа возвращаемый тип должен исключать старое поле и добавлять новое, иначе перезапись может дать несовместимое пересечение.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо добавить типизацию к функции addProperty, чтобы гарантировать безопасное расширение объектов новыми полями.
function addProperty(obj, key, value) {
return { ...obj, [key]: value };
}
const original = { name: "Alice" };
const updated = addProperty(original, "age", 25);
console.log(updated);
// Output: { name: 'Alice', age: 25 }
Ответ
Используйте generic-типы объекта, ключа и значения. Для известного литерального ключа возвращаемый тип должен исключать старое поле и добавлять новое, иначе перезапись может дать несовместимое пересечение.
function addProperty<T extends object, K extends PropertyKey, V>(
obj: T, key: K, value: V
): Omit<T, K> & Record<K, V> {
return { ...obj, [key]: value } as Omit<T, K> & Record<K, V>;
}
const updated = addProperty({ name: 'Alice' }, 'age', 25);
// updated.name: string; updated.age: number
Omit корректно отражает замену уже существующего поля при литеральном ключе. У этой учебной сигнатуры есть граница: широкий string или union ключей не доказывает наличие каждого поля Record. Для динамического ключа нужен более консервативный тип результата или предварительное сужение до конкретного литерала; не используйте assertion как runtime-валидацию.