✅ Новости WEB и WordPress, темы, плагины. Здесь мы делимся советами и лучшими решениями для веб-сайтов.

TypeScript: выбранные свойства необязательны с Partial & Omit

214

Когда вы используете утилиту Partialдля типа, она делает все свойства типа необязательными. Давайте посмотрим, как мы можем скомпоновать эту утилиту с другой Omit, чтобы сделать необязательными только определенные свойства этого типа. Наконец, мы создадим служебный тип, используя дженерики TypeScript, чтобы применить это к любому типу, который мы захотим.

Сделать все свойства типа необязательными

Утилиты Partialи Omitхорошо известны в области TypeScript, потому что они очень удобны, чтобы быстро применить их к типу и получить, по сути, новый тип. Partial<T>преобразует все ключи типа в необязательные. Если, например, у вас есть этот тип:

interface Band { lead: string guitar: string bass: string drums: string keyboard: string }

все свойства необходимы, когда что-то имеет этот тип. Если вы хотите назначить объект следующим образом:

const FooFighters: Band = { lead: 'Dave Grohl', guitar: 'Pat Smears', bass: 'Nate Mendel', drums: 'Taylor Williams', }

он потерпит неудачу, потому что в нем отсутствует keyboardсвойство. Теперь мы можем пометить это свойство как необязательное, и TypeScript легко позволяет нам это сделать. Самый простой способ сделать это — добавить вопросительный знак к его имени. В этом случае, если возможно отредактировать исходный тип, вы можете перейти к нему и изменить его следующим образом:

interface Band { lead: string guitar: string bass: string drums: string keyboard?: string }

Большой. Теперь предыдущее назначение будет выполнено успешно, потому что keyboardоно больше не требуется. Но что, если по какой-либо причине невозможно изменить исходный тип? Что вы можете быстро сделать в этих случаях, так это применить Partialк этому типу:

type NotAllTheBand = Partial const FooFighters: NotAllTheBand = { lead: 'Dave Grohl', guitar: 'Pat Smears', bass: 'Nate Mendel', drums: 'Taylor Williams', }

Это останавливает применение всех свойств, делая их необязательными. Возможно, иногда нам это нужно, но что, если мы просто хотим сделать только одно свойство необязательным и избежать изменения исходного типа?

Удаление свойств из типа

Прежде чем мы перейдем к ней и посмотрим, как она работает, давайте посмотрим еще одну утилиту, которая поможет нам в этом: Omit. Этот служебный тип удаляет свойства из типа, к которому он применяется. Пока Partialне принимает других аргументов, кроме типа, Omitпринимает тип плюс свойства, которые вы хотите удалить: Omit<T, K>.

Это не Partialто, что делает их необязательными: Omitполностью вычеркнет их из типа. Когда вы используете Partial<Band>это, как если бы вы сделали это:

interface Band { lead?: string guitar?: string bass?: string drums?: string keyboard?: string }

Однако, когда вы используете Omit<Band, 'keyboard'>, это как если бы вы сделали это:

interface Band { lead: string guitar: string bass: string drums: string }

Теперь это начинает иметь смысл, верно? Можете ли вы представить, что мы могли бы сделать в TypeScript, если бы у нас был тип, у которого все свойства исходного набора были заданы как необязательные, и другой тип, у которого есть только те свойства, которые нам нужны? Если бы только был способ… пересекать эти типы, верно?

Пересекающиеся типы

Да, в TypeScript есть способ использовать амперсанд &, оператор пересечения типов. Этот оператор, учитывая два типа, создает новый со свойствами, принадлежащими обоим типам:

interface SomeType { propA: string propB: number } interface AnotherType { propC: boolean propD: Array } type IntersectedType = SomeType & AnotherType

К настоящему времени вы, вероятно, поняли: мы собираемся пересечь партиализированный тип и тип, у которого мы удалили некоторые свойства.

Сделать выбранные свойства типа необязательными

Попробуем разобраться. При изучении TypeScript важно рационализировать то, что происходит с нашими типами.

Мы собираемся получить тип, все свойства которого установлены как необязательные, благодаря Partialпримененному к нему. Далее мы собираемся пересечь его с типом, свойства которого были удалены с помощью Omit. Давайте посмотрим пример:

interface SomeType { propA: string propB: number } type OptionalPropB = Partial & Omit

Теперь у нас есть новый тип без изменения исходного типа, который выглядит следующим образом:

type OptionalPropB = { propA: string propB?: string }

Это происходит потому, что мы берем свойства propA?и propB?из типа, созданного с помощью, Partialи пересекаем их с propAтипом, созданным с помощью Omit.

Общие утилиты TypeScript

Хорошо, теперь наш новый тип работает, и мы можем помечать только выбранные свойства как необязательные, не изменяя исходный тип. Однако эта линия

type OptionalPropB = Partial & Omit

Слишком многословно, довольно уродливо и утомительно писать каждый раз. Что еще более важно, он не будет работать для другого типа, нам придется каждый раз писать его заново. Можем ли мы сделать его короче и красивее, чтобы он работал для любого типа? Да, TypeScript позволяет нам использовать здесь дженерики и создавать собственный служебный тип:

type Optional = Partial & Omit

И теперь у нас есть собственный служебный тип TypeScript, реализованный с помощью универсальных шаблонов, которые мы можем использовать, чтобы сделать выбранные свойства типа необязательными для любого типа. Мы можем использовать это так:

type TypeWithOptionalProp = Optional

Вы заметите, что сигнатура похожа на Omit: эта утилита принимает тип для работы и свойства, которые будут сделаны необязательными. Если у вас их больше, вы можете использовать оператор объединения:

type TypeWithOptionalProps = Optional

Заключительные слова

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

Мир дженериков и утилит в TypeScript просто фантастический. Займитесь этим и начните экспериментировать!

Источник записи: startfunction.com

Этот веб-сайт использует файлы cookie для улучшения вашего опыта. Мы предполагаем, что вы согласны с этим, но вы можете отказаться, если хотите. Принимаю Подробнее