当我映射和展平数组时,TypeScript 会错误地出错?
TypeScript incorrectly errors when I map and flat an array?
我正在使用 GraphQL Codegen 从我的 GraphQL 模式生成 TypeScript 类型。这是我的查询,我使用了一个片段,因此它只有一种易于导出的类型:
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
}
}
}
}
返回的数据如下所示:
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
}
]
}
]
}
]
我可以在新变量上使用这种类型,它按预期工作:
const childrenCurrent: ReservationsPageFragment['children'] = roomsForSchoolSettingAll.find(
(room) => room.id === selectedRoomId,
)?.children;
然而,当我尝试在另一个变量上使用它时,出现 TypeScript 错误:
const childrenAll: ReservationsPageFragment['children'] = roomsForSchoolSettingAll
.map((room) => room.children)
.flat();
TS2322: Type '(({ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }) | null | undefined)[]' is not assignable to type 'Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>[]'. Type '({ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }) | null | undefined' is not assignable to type 'Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>'. Type 'undefined' is not assignable to type 'Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>'.
抱歉,但从你的问题来看,我无法理解你是在寻找错误原因的解释,还是只是寻找一种使其起作用的方法。
在第一种情况下,我不是 GraphQL 高手,所以你可以忽略我的回答,寻找了解 GraphQL 的人的答案。
在第二种情况下,您可以尝试不指定 childrenAll
类型:
const childrenAll = roomsForSchoolSettingAll
.map((room) => room.children)
.flat();
或使用类型转换:
const childrenAll: ReservationsPageFragment['children'] = roomsForSchoolSettingAll
.map((room) => room.children)
.flat() as unknown as ReservationsPageFragment['children'];
如果您在错误消息文本中进行替换,它会变得更具可读性:
TS2322:
Type '((X) | null | undefined)[]' is not assignable to type
'Maybe<X>[]'.
Type '(X) | null | undefined' is not assignable to
type 'Maybe<X>'.
Type 'undefined' is not assignable to type
'Maybe<X>'.
其中 X 代表
{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile,
"id" | "name"> & { registrationToday?: ({ __typename?:
"Registration" | undefined; } & Pick<...> & { ...; }) | null |
undefined; }
现在我们可以看到编译器指示类型 Maybe<X>
不能保存值 undefined
。
为了满足编译器,你有多种选择
- 过滤掉
undefined
个值
- 使用类型转换(如 Daniele Ricci 的回答中所述)
- 更改
Maybe
类型的定义以允许 undefined
值
如果您选择修改 Maybe
类型,在 GraphQL 代码生成器中有一个如何执行此操作的示例 documentation:
我正在使用 GraphQL Codegen 从我的 GraphQL 模式生成 TypeScript 类型。这是我的查询,我使用了一个片段,因此它只有一种易于导出的类型:
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
}
}
}
}
返回的数据如下所示:
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
}
]
}
]
}
]
我可以在新变量上使用这种类型,它按预期工作:
const childrenCurrent: ReservationsPageFragment['children'] = roomsForSchoolSettingAll.find(
(room) => room.id === selectedRoomId,
)?.children;
然而,当我尝试在另一个变量上使用它时,出现 TypeScript 错误:
const childrenAll: ReservationsPageFragment['children'] = roomsForSchoolSettingAll
.map((room) => room.children)
.flat();
TS2322: Type '(({ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }) | null | undefined)[]' is not assignable to type 'Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>[]'. Type '({ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }) | null | undefined' is not assignable to type 'Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>'. Type 'undefined' is not assignable to type 'Maybe<{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }>'.
抱歉,但从你的问题来看,我无法理解你是在寻找错误原因的解释,还是只是寻找一种使其起作用的方法。
在第一种情况下,我不是 GraphQL 高手,所以你可以忽略我的回答,寻找了解 GraphQL 的人的答案。
在第二种情况下,您可以尝试不指定 childrenAll
类型:
const childrenAll = roomsForSchoolSettingAll
.map((room) => room.children)
.flat();
或使用类型转换:
const childrenAll: ReservationsPageFragment['children'] = roomsForSchoolSettingAll
.map((room) => room.children)
.flat() as unknown as ReservationsPageFragment['children'];
如果您在错误消息文本中进行替换,它会变得更具可读性:
TS2322:
Type '((X) | null | undefined)[]' is not assignable to type 'Maybe<X>[]'.
Type '(X) | null | undefined' is not assignable to type 'Maybe<X>'.
Type 'undefined' is not assignable to type 'Maybe<X>'.
其中 X 代表
{ __typename?: "ChildProfile" | undefined; } & Pick<ChildProfile, "id" | "name"> & { registrationToday?: ({ __typename?: "Registration" | undefined; } & Pick<...> & { ...; }) | null | undefined; }
现在我们可以看到编译器指示类型 Maybe<X>
不能保存值 undefined
。
为了满足编译器,你有多种选择
- 过滤掉
undefined
个值 - 使用类型转换(如 Daniele Ricci 的回答中所述)
- 更改
Maybe
类型的定义以允许undefined
值
如果您选择修改 Maybe
类型,在 GraphQL 代码生成器中有一个如何执行此操作的示例 documentation: