【问题标题】:Resolve __typename union解决 __typename 联合
【发布时间】:2019-10-10 01:50:02
【问题描述】:

假设我有这个工会:

export type IBookmarkItemFragment =
  | ({ __typename: "Story" } & {
      story: number;
    })
  | ({ __typename: "Product" } & {
      product: number;
    })
  | ({ __typename: "Project" } & {
      project: number;
    });

我想要基于__typeame.filter.map。比如:

bookmarks
  .filter(bookmark => {
    return bookmark.__typename === "Project";
  })
  .map(project => {
    return project.project;
  });

我如何确保在地图中project 将解析为:

({ __typename: "Project" } & {
  project: number;
})

【问题讨论】:

    标签: typescript graphql


    【解决方案1】:

    您必须明确声明该函数是带有注释的类型保护:

    export type IBookmarkItemFragment =
    | ({ __typename: "Story" } & {
        story: number;
        })
    | ({ __typename: "Product" } & {
        product: number;
        })
    | ({ __typename: "Project" } & {
        project: number;
        });
    
    declare let bookmarks: IBookmarkItemFragment[]
    bookmarks
    .filter((bookmark):bookmark is Extract<IBookmarkItemFragment, { __typename: "Project"}>   => {
        return bookmark.__typename === "Project";
    })
    .map(project => {
        return project.project;
    });
    

    或者只是为了好玩,如果我们想概括类型守卫,我们可以创建一个守卫工厂,它适用于任何常见的标记联合。

    export type IBookmarkItemFragment =
    | ({ __typename: "Story" } & {
        story: number;
        })
    | ({ __typename: "Product" } & {
        product: number;
        })
    | ({ __typename: "Project" } & {
        project: number;
        });
    
    function guardFactory<T, K extends keyof T, V extends string & T[K]>(k: K, v: V) : (o: T) => o is Extract<T, Record<K, V>> {
        return function (o: T): o is Extract<T, Record<K, V>> {
            return o[k] === v
        }
    }
    declare let bookmarks: IBookmarkItemFragment[]
    bookmarks
    .filter(guardFactory("__typename", "Project"))
    .map(project => {
        return project.project;
    });
    

    【讨论】:

    • 优秀的答案!你是如何使__typename 成为常​​数的?说我想像这样使用它:.filter(byTypename("Project"))
    • 它需要知道标记字段,因此您可以将guardFactory 更改为仅适用于具有__typename 的类型,或者您必须像我上面所做的那样指定它。 __typenamekeyof T,因此将根据预期的项目类型对其进行检查。这里的诀窍是T 可以从返回类型中推断出来。所以直接在过滤器中使用它是必须的,因为它可以让我们知道我们在区分什么联合
    猜你喜欢
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多