Копирование только указанных полей объекта в одну операцию

Есть ли способ поверхностного копирования в новый объект только указанных полей другого объекта в одну операцию (условно говоря), чтобы не перечислять поля дважды?

Например что-то вроде этого (псевдокод):

let partialCopy{ nameOne, nameTwo, goodName } = originalObject;

Эта задача легко получается через деструктуризацию, но при этом приходится перечислять поля дважды, что повышает вероятность ошибок и выглядит громоздко при длинных списках:

let { nameOne, nameTwo, goodName } = originalObject,
    partialCopy = { nameOne, nameTwo, goodName };

Примечание 1: originalObject в примере может иметь много свойств, а нужно взять только указанные из него.

Примечание 2: функции возвращают непонятный тип в случае typescript, поэтому менее желательны. Если решение - это функция, то она должна вывести тип получаемого объекта, как это легко получается в примере с деструктуризацией.


Ответы (1 шт):

Автор решения: Pavel Grishaev

Поскольку нет хорошего ответа на 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.

→ Ссылка