说我有这个工会:
export type IBookmarkItemFragment =
| ({ __typename: "Story" } & {
story: number;
})
| ({ __typename: "Product" } & {
product: number;
})
| ({ __typename: "Project" } & {
project: number;
});
我希望基于.filter
的{{1}}和.map
。像这样:
__typeame
我如何确保在地图bookmarks
.filter(bookmark => {
return bookmark.__typename === "Project";
})
.map(project => {
return project.project;
});
中将解析为:
project
答案 0 :(得分: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;
});