这种类型:
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
// 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 的 Playground。