graphql codegen - TypeScript ger felaktigt fel när jag mappar och plattar ut en array?


Jag använder GraphQL Codegen för att generera TypeScript-typer från mitt GraphQL-schema. Här är min query, jag har använt ett fragment så att det har sin egen typ som är enkel att exportera:

query reservationsPage($schoolSettingId: Int!, $day: UnixDate!) {
  roomsForSchoolSettingAll(schoolSettingId: $schoolSettingId) {
    ...reservationsPage
  }
}

fragment reservationsPage on Room {
    id
    name
    children {
      id
      name
      registrationToday(day: $day) {
        id
        checkIn
        checkOut
        importantInformation
        plannedCheckOut
        absent
        pickUpBy {
          id
          name
        }
      }
    }
}

De data som returneras ser ut ungefär så här:

const res = [
  {
    id: 1,
    __typename: "Room",
    name: 'Name 1',
    children: []
  },
  {
    id: 2,
    __typename: "Room",
    name: 'Name 2',
    children: [
      {
        id: 3,
        __typename: "ChildProfile",
        name: 'James',
        registration: [
          {
            id: 4,
            __typename: "Registration",
            checkIn: "06:00:00",
            checkOut: "14:00:00",
            absent: null,
            importantInformation: null,
            pickUpBy: null
            plannedCheckOut: null  
          }
        ]
      }
    ]
  }
]

Jag kan använda den här typen på en ny variabel och det fungerar som förväntat:

const childrenCurrent: ReservationsPageFragment['children'] = roomsForSchoolSettingAll.find(
    (room) => room.id === selectedRoomId,
  )?.children;

Men när jag försöker använda det på en annan variabel får jag ett TypeScript-fel:

const childrenAll: ReservationsPageFragment['children'] = roomsForSchoolSettingAll
  .map((room) => room.children)
  .flat();

TS2322: Typ ''(({ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }) | null | undefined)[]'' kan inte tilldelas typen ''Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>[]'. Typ ''({ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<. ..> & { ...; }) | null | undefined; }) | null | undefined' kan inte tilldelas typen 'Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>'. Typen 'undefined' kan inte tilldelas typen 'Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>'.

Svar #1

Om du gör en ersättning i felmeddelandetexten blir det mer läsbart:

TS2322:
Typen '((X) | null | undefined)[]' kan inte tilldelas typen 'Maybe<X>[]'.
Typen '(X) | null | undefined' kan inte tilldelas typen 'Maybe<X>'.
Typen 'undefined' kan inte tilldelas typen 'Maybe<X>'.

där X står för

{ __typename?: "ChildProfile" | undefined; } & Välj<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Välj<...> & { ...; }) | null | undefined; }

Nu kan vi se att kompilatorn indikerar att typen Maybe<X> inte kan innehålla ett värde undefined.
För att tillfredsställa kompilatorn har du flera alternativ

  • filtrera bort undefined-värden
  • använd en typomvandling (som nämnts i Daniele Riccis svar)
  • ändra definitionen av Maybe-typen för att tillåta undefined-värden

Om du väljer att ändra Maybe-typen finns ett exempel på hur man gör det i dokumentationen för GraphQL-kodgeneratorn:

Svar #2

Förlåt, men utifrån din fråga kan jag inte förstå om du letar efter en förklaring till orsaken till felet eller bara ett sätt att få det att fungera.

I det första fallet är jag inte en GraphQL-mästare, så du kan ignorera mitt svar och leta efter ett svar från någon som kan GraphQL.

I det andra fallet kan du försöka att inte specificera typen childrenAll:

const childrenAll = roomsForSchoolSettingAll
  .map((room) => room.children)
  .flat();

eller använda typomvandling:

const childrenAll: ReservationsPageFragment['children'] = roomsForSchoolSettingAll
  .map((room) => room.children)
  .flat() as unknown as ReservationsPageFragment['children'];

Relaterade artiklar