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
那么它保证 x
是 Whatever
类型.
在您的示例中,TypeScript 考虑了所有三个类:
所以你可以为 filter()
定义谓词函数,如下所示:
filter((x: Shape): x is Square => x.kind === 'square')
现在它将正确地只考虑 Square
类:
查看现场演示:https://stackblitz.com/edit/rxjs6-demo-z9lwxe?file=index.ts
关于javascript - Typescript 使用 Rx.js 过滤器运算符区分联合类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50525063/