javascript - Typescript 使用 Rx.js 过滤器运算符区分联合类型?

标签 javascript typescript redux rxjs redux-observable

typescript 支持discriminated unions . 如何将与 Rxjs 相同的概念扩展到 filter下面例子中的运算符

interface Square {
    kind: 'square';
    width: number;
}

interface Circle {
    kind: 'circle';
    radius: number;
}

interface Center {
    kind: 'center';
}

type Shape = Square | Circle | Center;

const obs$: Observable<Shape> = of<Shape>({ kind: 'square', width: 10 });

// Expected type: Observable<Square>
// Actual type: Observable<Shape>
const newObs$ = obs$.pipe(
    filter((x) => x.kind === 'square')
);

在上面的代码片段中,我希望看到 newObs$ 的类型被推断为:Observable<Square> .但显然,TypeScript不会那样做。

如何实现?我是否达到了 TypeScript 类型推断的极限?

我正在寻找它,因为它在 Redux + Redux-Observable 中似乎非常有用代码库。

最佳答案

实际上,您可以使用 TypeScript 类型保护来做到这一点。请参阅 http://www.typescriptlang.org/docs/handbook/advanced-types.html 中的“类型保护和区分类型”部分

这里的关键是 function isWhatever(x: any): x is Whatever => ... 语法。

这基本上是说,如果 isWhatever 函数返回 true 那么它保证 xWhatever 类型.

在您的示例中,TypeScript 考虑了所有三个类:

without-typeguard

所以你可以为 filter() 定义谓词函数,如下所示:

filter((x: Shape): x is Square => x.kind === 'square')

现在它将正确地只考虑 Square 类:

with-typeguard

查看现场演示:https://stackblitz.com/edit/rxjs6-demo-z9lwxe?file=index.ts

非常相似的问题:https://github.com/ReactiveX/rxjs/issues/2340

关于javascript - Typescript 使用 Rx.js 过滤器运算符区分联合类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50525063/

相关文章:

javascript - 查询字符串检查不同页面上的复选框

javascript - 获取 "window"对象进行评估,并列出所有变量? Javascript 评估内联 html

javascript - 饼图而不是谷歌地图中的标记簇图标

javascript - Typescript 严格类型检查不适用于可观察中的字符串和数组

javascript - 想要将 IF 语句与 JSON 一起使用

angular - 如何调试 angular 项目中损坏的 ng lint

asp.net - Angular 2 与 RequireJS 导入错误

javascript - 如何在组件触发的函数中使用 to action?

javascript - 如何解决 react-redux 应用程序中添加评论和删除评论的问题

javascript - 使用 mochajs 测试 reactjs 组件