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åtaundefined-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'];
