typescript - 从 typescript 中的联合引用复杂类型

标签 typescript graphql-codegen

我正在使用 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/

相关文章:

visual-studio - 如何使这个简单的 TypeScript + React 应用程序与 Visual Studio 2015 一起工作?

typescript - 无法找到以下指针的任何 GraphQL 类型定义 : src/**/*. graphql

typescript - 自动生成的函数的Typesafe包装,然后仅通过使用 `__typename`作为参数来动态调用。 typescript

javascript - 为什么我要使用 RxJS interval() 或 timer() 轮询而不是 window.setInterval()?

javascript - 动态地将一个组件追加到另一组件中

css - Angular2 - 将 [_ngcontent-mav-x] 添加到样式

reactjs - Ant.design 没有检测到 Form.Item React 中的自定义输入组件

当我映射和展平数组时,TypeScript 会错误地出错?

reactjs - 使用 @graphql-codegen/cli 获取 graphql 查询中的子类型