Как исключить «УДАЛЕНИЕ» многих свойств из объекта?

У меня есть два метода, которые возвращают следующие типы Pick<T, K> и Omit<T, K>, где Omit — это type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>. У меня возникают проблемы с удалением нескольких свойств объекта.

У меня есть метод pickOne, который выбирает одно свойство из объекта, метод pickMany, который выбирает несколько свойств из объекта, и метод omitOne, который удаляет одно свойство из объекта. Я хотел бы иметь метод OmitMany для удаления нескольких свойств из объекта, но я застрял при исправлении ошибок типа в методе.

Реализация методов:

export let pickOne = <T, K extends keyof T>(entity: T, props: K ): Pick<T, K> => {
    return { [props] : entity[props] } as Pick<T, K>
}

export let pickMany = <T, K extends keyof T>(entity: T, props: K[]) => {
   return props.reduce((s, prop) => (s[prop] = entity[prop], s) , {} as Pick<T, K>)
}

export let omitOne = <T, K extends keyof T>(entity: T, prop: K): Omit<T, K> => {
    const { [prop]: deleted, ...newState} = entity
    return newState
}

// And the OmitMany for so far I tried, the problem is with storing the entity
// in a temporary variable. This function only omits the last property in the
// the array. I would like an implementation simular to pickMany.
export let omitMany = <T, K extends keyof T>(entity: T, props: K[]): Omit<T, K> => {
    let result = entity as Omit<T, K>
    props.forEach(prop => {
        result = omitOne(entity, prop)
    })
    return result
}

Я ожидаю, что вывод omitMany({x: 1, y: 2, z: 3, r: 4}, ['x', 'y']) будет объектом типа {z: number, r: number}, но точно знаю, что вывод является объектом типа {x: number, z: number, r: number}

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
3
0
552
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Ваша проблема имеет мало общего с машинописью. Типы работают так, как вы ожидаете, для omitMany, единственная проблема заключается в том, что во время выполнения он не удаляет все свойства, которые вы ожидаете, и это вызвано тем фактом, что вы вызываете omitOne на entity вместо предыдущего результата . К сожалению, это требует некоторых утверждений типа, но это сработает:

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

let omitOne = <T, K extends keyof T>(entity: T, prop: K): Omit<T, K> => {
    const { [prop]: deleted, ...newState } = entity
    return newState
}

let omitMany = <T, K extends keyof T>(entity: T, props: K[]): Omit<T, K> => {
    let result = entity as Omit<T, K>
    props.forEach(prop => {
        result = omitOne(result, prop as unknown as keyof Omit<T, K>) as Omit<T, K>
    })
    return result
}

let o = omitMany({ x: 1, y: 2, z: 3, r: 4 }, ['x', 'y'])
console.log(o)

Игровая площадка

Начиная с TS 3.5 и стандартного типа Omit:

function omit<T, K extends keyof T>(obj: T, ...props: K[]): Omit<T, K> {
    return props.reduce((o, k) => { delete o[k]; return o; }, { ...obj });
}

Другие вопросы по теме