我正在使用 graphql-codegen
从我的 graphQL 查询生成类型。
结果有时非常复杂,特别是当 unions
时涉及。
这是一个具体的例子
export type GroupQuery = { __typename?: 'Query' } & {
group?: Maybe<
{ __typename?: 'Group' } & Pick<
Group,
'id' | 'name'
> & {
criterions: Array<
{ __typename?: 'kindA' } & Pick<SomeModel, 'id' | 'type'> |
{ __typename?: 'kindB' } & Pick<SomeOtherModel, 'id' | 'type' | 'count'>
>
}
}
所以我试图做的是能够引用基于
__typename
的联合的特定案例let kindB: NonNullable<GroupQuery['group']>['criterions'][0]// not sure where to go from here.
也许是实用程序类型?
最佳答案
这个类型:
type T = NonNullable<GroupQuery['group']>['criterions'][0]`
将被解析为这种类型:
type T = {
__typename?: "kindA" | undefined;
id: number;
name: string;
} | {
__typename?: "kindB" | undefined;
id: number;
name: string;
}
那么您真正要问的是如何获得工会的分支机构:
__typename === 'kindB'
在这种情况下,您可以使用交叉路口
&
过滤联合类型。一般来说,它的工作原理是这样的:type T = ("A" | "B" | "C") & "A" // "A"
Playground
因此,您可以使用交集使联合仅解析为可以匹配相交类型的类型。
type KindB =
NonNullable<GroupQuery['group']>['criterions'][0] & { __typename: 'kindB' }
现在
KindB
解析为这种类型:type KindB = {
__typename?: "kindB" | undefined;
id: number;
name: string;
} & {
__typename: 'kindB';
}
如您所见,
kindA
工会的成员不再存在,并且工会的剩余成员正在与 { __typename: 'kindB' }
相交.如果你应用那个交集,它会减少到:type KindB = {
__typename: "kindB";
id: number;
name: string;
}
Playground with working code
通过一些重构,您甚至可以使用一个不错的泛型类型别名使其变得非常好:
// Union of all criterion types
type GroupQueryCriterions =
NonNullable<GroupQuery['group']>['criterions'][number]
// Get the branch of the criterions union that has a specific typename.
type GroupQueryCriterionType<T extends GroupQueryCriterions['__typename']> =
GroupQueryCriterions & { __typename: T }
// Get a specific criterion type.
type KindB = GroupQueryCriterionType<'kindB'>
Playground
关于typescript - 从 typescript 中的联合引用复杂类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62347781/