деструктуризация больших объектов при использовании карты с машинописным текстом

Я все еще относительно новичок в typeScript и немного борюсь с аннотациями в проекте, над которым я работаю с различными данными из конечной точки GraphQL.

Структура данных может измениться позже, поэтому я использовал Apollo Client для создания соответствующих типов TypeScript для различных запросов, чтобы не вводить их вручную. Это работает хорошо: Пока все хорошо!

Однако, когда я хочу отобразить различные данные, у меня возникают проблемы: в основном, когда я использую функцию map() и начинаю деструктурировать данные, мне трудно найти примеры того, как это сделать? Я не уверен, сталкиваюсь ли я с конфликтами имен? Различные ошибки мне непонятны.

Пример: (это фрагмент более крупного блока кода — если я наведу указатель мыши на seoDataObject, я увижу, что он правильно аннотирован, как и ожидалось — это массив объектов:

const seoDataObject: (AllUsersSeo_users_edges | null)[] | ноль | неопределенный)


interface AllUsersSeo_users_edges {
  __typename: "RootQueryToUserConnectionEdge";
  /**
   * The item at the end of the edge
   */
  node: AllUsersSeo_users_edges_node | null;
}

const seo = seoDataObject?.map(({ node }) => node).find((node) => node.id === id)?.seo;

Затем я получаю следующую ошибку:

var node: any
Property 'node' does not exist on type 'AllUsersSeo_users_edges | null'.ts(2339)

Как бы я переписал это, используя машинописный текст?

«узел» существует для каждого объекта seoDataObject, но во фрагменте кода «узел» также является параметром функции карты, поэтому я просто не могу понять, как правильно это сделать в Typescript?


person Lars Ejaas    schedule 09.06.2021    source источник
comment
Я сильно ограничил это - на самом деле это всего лишь второстепенная вещь. Все сводится к аннотациям, которые предоставляет ApolloClient: ``` края: (AllUsers_users_edges | null)[] | нулевой; ``` если я вручную изменю это определение и удалю аннотацию 'или null', ошибка исчезнет: ``` края: (AllUsers_users_edges)[] | нулевой; ``` Но как я могу переписать это, чтобы исключить нулевые значения? можно ли здесь использовать условный оператор? ``` const seo = seoDataObject?.map(({ node? }) =› node).find((node) =› node.id === id)?.seo; ``` Я знаю, что это неправильно (узел?), но не уверен, что сделал это правильно?   -  person Lars Ejaas    schedule 09.06.2021


Ответы (1)


Я не совсем понял, что вы на самом деле спрашиваете, вы просто хотите найти seo по идентификатору, и он может быть в результатах, которые могут быть массивом нулевых значений или самим нулем?

В таком случае const seo = seoDataObject?.filter(x => x.node).find(x => x.node.id === id)?.node.seo;

person Andreas Turku    schedule 09.06.2021
comment
Да, мне очень жаль, что это так грязно! Когда Apollo-Client предоставляет аннотации, все они имеют эту аннотацию «или null» (| null). Я повторно загружу новые объекты JSON из клиента Apollo, поэтому не могу вручную редактировать аннотацию. При работе с объектами я обычно просто использую необязательную цепочку (.?), чтобы учесть это, но борюсь с этим при использовании map(). Но, возможно, filter() — это способ обойти эту проблему — я пока не думал — я попробую и посмотрю, как это работает! - person Lars Ejaas; 09.06.2021
comment
Андреас, я использовал ваше решение, немного модифицированное: ```const seo = seoDataObject.filter(x => x?.node).find(x => x?.node?.id === id)?.node?. поисковая оптимизация; ``` Но мне пришлось обратиться к оператору утверждения Non-null (!) в нескольких случаях, чтобы сообщить машинописному тексту, что данные не являются нулевыми или неопределенными. Код выдаст ошибку несколькими строками ранее, если данные равны нулю или не определены. Я напишу несколько тестов, чтобы проверить наличие данных GraphQL. Пример, который я сделал в предыдущей строке: ``` const seoDataObject = seoData?.data?.users?.edges!; ``` Спасибо за помощь, Андреас! - person Lars Ejaas; 10.06.2021