TypeScript中is关键字解析及Angular路由场景的相关疑问
TypeScript/Angular中filter类型谓词用法解答
先明确原代码的作用:通过filter操作符结合类型谓词(routingEvent is NavigationEnd),从Angular路由事件流中只保留NavigationEnd类型的事件,同时让TypeScript编译器知道过滤后流中的事件类型是NavigationEnd,实现类型收窄。
疑问1:使用map()并声明routingEvent is NavigationEnd会不会更高效?
不会,而且逻辑完全错误。
filter的作用是过滤:只保留回调返回true的项,直接剔除不符合条件的路由事件(比如NavigationStart、RoutesRecognized等)。map的作用是转换:会处理流中的每一个项并输出,无法剔除非NavigationEnd的事件。如果强行在map里用类型谓词,不仅会保留所有事件(包括非目标类型),还会给TypeScript错误的类型断言——运行时那些非NavigationEnd的事件依然存在,只是被错误标注了类型,会导致后续代码出现运行时错误。
从效率上看,filter直接过滤掉不需要的项,比map处理所有项更高效。
疑问2:在filter()中声明routingEvent is NavigationEnd后,是否会改变订阅时的输出?如果会的话,为何不能直接返回true?
- 类型谓词不会改变运行时的输出,它只是给TypeScript编译器的类型提示。运行时决定输出的依然是回调函数返回的布尔值:只有当
routingEvent instanceof NavigationEnd为true时,这个事件才会被保留到后续的流中。 - 不能直接返回
true的原因:- 运行时会保留所有路由事件,不符合“只处理
NavigationEnd”的业务逻辑; - TypeScript不会认可这个类型断言——类型谓词的可信度依赖于回调的逻辑判断,只有当你通过
instanceof验证了类型,编译器才会相信返回true时的类型是NavigationEnd。如果直接返回true,编译器无法确认输入的类型,也就不会进行类型收窄,订阅时拿到的依然是any或RouterEvent类型,失去了类型谓词的意义。
- 运行时会保留所有路由事件,不符合“只处理
内容的提问来源于stack exchange,提问作者Issac Howard
相关产品推荐
相关产品推荐

