Копирование только указанных полей объекта в одну операцию
Есть ли способ поверхностного копирования в новый объект только указанных полей другого объекта в одну операцию (условно говоря), чтобы не перечислять поля дважды?
Например что-то вроде этого (псевдокод):
let partialCopy{ nameOne, nameTwo, goodName } = originalObject;
Эта задача легко получается через деструктуризацию, но при этом приходится перечислять поля дважды, что повышает вероятность ошибок и выглядит громоздко при длинных списках:
let { nameOne, nameTwo, goodName } = originalObject,
partialCopy = { nameOne, nameTwo, goodName };
Примечание 1: originalObject в примере может иметь много свойств, а нужно взять только указанные из него.
Примечание 2: функции возвращают непонятный тип в случае typescript, поэтому менее желательны. Если решение - это функция, то она должна вывести тип получаемого объекта, как это легко получается в примере с деструктуризацией.
Ответы (1 шт):
Поскольку нет хорошего ответа на js пока, сделал на typescript в качестве решения с сохранением типов такую функцию:
objectPartialCopy<From, T extends (keyof From)[]>( obj: From, ...keys: T ): Pick<From, T[number]> {
let resultObj: Pick<From, T[number]> = {} as any;
keys.forEach(( key: keyof From )=>{
resultObj[key] = obj[key];
});
return resultObj;
}
Пользоваться можно так:
let copy = objectPartialCopy( window, 'innerWidth', 'innerHeight' );
Преимущества данного подхода показаны на следующих скриншотах:
Подсказки ключей в IDE:
Подсвечивает неверные ключи в IDE:
Верный тип скопированного объекта (тип не теряется):
При присвоении неверного типа ожидаемо ругается:
Недостатки - это всё-таки функция, а не простой оператор или подход, и может не поддерживаться в IDE для js.



