От шума и суеты напряженного утреннего Scrum Meeting до тихого, сосредоточенного гула ночного спринта по программированию, мои дни в качестве разработчика программного обеспечения совсем не обыденны. Среди различных проблем, связанных с работой, одна вещь остается неизменной: стремление к постоянному совершенствованию своего ремесла. Каждый день — это возможность совершенствоваться, учиться и расти.

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

Позвольте мне подготовить сцену: я разрабатываю проект, который включает отправку пользовательских данных в REST API Microsoft Graph. Пользовательские данные включают поле jobTitle, которое обычно присутствует, но иногда может отсутствовать. Graph API не очень прощает нулевые значения — если он встречает нулевой атрибут, он выдает ошибку 400 Bad Request. Именно тогда в игру вступила функция необязательных атрибутов TypeScript.

Введение в проблему

Наш первоначальный подход был простым: прямой доступ к необязательному свойству. Однако это привело к 400 ошибкам, когда jobTitle отсутствовал или имел значение null.

const data = {
    // other properties...
    jobTitle: payload.jobTitle,  // What if this doesn't exist?
};

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

Обработка необязательных свойств с расширенным синтаксисом

В первом реализованном мной решении используется синтаксис распространения (...) в сочетании с условным рендерингом.

const data = {
    displayName: payload.displayName,
    givenName: payload.givenName,
    id: payload.objectId,
    mail: payload.mail,
    surname: payload.surname,
    ...(payload.jobTitle && { jobTitle: payload.jobTitle }),
};

В этом подходе я создал новый объект, включающий все свойства из payload. Затем я условно добавил свойство jobTitle, только если оно было доступно и верно в payload. Если бы payload.jobTitle было нулевым, оно не было бы включено в data, тем самым защищая нас от ужасных 400 ошибок.

Это новаторское использование оператора распространения и условного рендеринга позволило коду элегантно обрабатывать необязательные свойства, устраняя непредвиденные ошибки.

Освоение типа частичной полезности

Еще одна мощная функция в арсенале TypeScript — служебный тип Partial. Эта функция превращает все свойства объекта в необязательные.

const data: Partial<IApiRequestData> = {
    displayName: payload.displayName,
    givenName: payload.givenName,
    id: payload.objectId,
    mail: payload.mail,
    surname: payload.surname,
};

if (payload.jobTitle) {
    data.jobTitle = payload.jobTitle;
}

Используя Partial<IApiRequestData>, я указал, что вполне допустимо отсутствие любого свойства data. Затем мы добавили jobTitle к data только тогда, когда он существовал в payload. Эта стратегия представляла собой чистый и интуитивно понятный способ работы с необязательными свойствами.

Вот и все — реальный отчет о том, как мы использовали TypeScript для элегантной обработки необязательных свойств в запросах REST API Microsoft Graph. Именно эти постепенные улучшения постоянно улучшают нашу кодовую базу, уменьшают количество ошибок и, в конечном счете, делают наш путь в разработке программного обеспечения более плавным и продуктивным. Помните, что путь к освоению TypeScript — это марафон, а не спринт, и каждый шаг вперед — это прогресс.

Ура!