我想了解我在 Typescript/Angular 中看到的特定模式,如下所示:
this.subscription = this.router.events
.pipe(
filter((routingEvent: any): routingEvent is NavigationEnd => routingEvent instanceof NavigationEnd),
据我了解,“is”关键字缩小了type的范围。这意味着 Angular 的 RouterEvent 类变成了它的子类
NavigationEnd
。然后我们检查 routingEvent
是否属于实例 NavigationEnd
。我有两个问题:
routingEvent is NavigationEnd
不是更高效吗?filter()
中,我们说过routingEvent is NavigationEnd
。当我们订阅时,这会改变输出吗?如果是这样,为什么我们不能直接 return true
因为我们实际上只是声明了 routingEvent is NavigationEnd
?如果这些问题有缺陷,请原谅我,因为我是 Typescript 的新手,但如果有人可以帮助我,那就太好了。
打字稿中的
is
关键字用于描述 谓词。
谓词用于用户定义的类型防护。
当你有
(routingEvent: any): routingEvent is NavigationEnd => routingEvent instanceof NavigationEnd),
Typescript 适用于您问题中的
static type checking
,这意味着我们不操作值,我们只是使用 Typescript 定义类型来捕获由于分配的类型不正确而导致的最大类型错误。
现在让我们回答你的问题。
如果我们使用'map()'并说routingEvent是NavigationEnd,不是会更高效吗?
Ans: 不会,因为
map
会返回所有值,这里 filter
的目的是使用 javascript instanceof
运算符单独过滤掉所有 NavigationEnd
事件,因此所有其他事件(例如 NavigationStart
等不会被订阅)这就是我们使用过滤器的原因!其次,router.events
有一个类型Event_2
,下面是它的类型定义
declare type Event_2 = NavigationStart | NavigationEnd |
NavigationCancel | NavigationError | RoutesRecognized |
GuardsCheckStart | GuardsCheckEnd | RouteConfigLoadStart |
RouteConfigLoadEnd | ChildActivationStart | ChildActivationEnd |
ActivationStart | ActivationEnd | Scroll | ResolveStart |
ResolveEnd | NavigationSkipped;
正如你所看到的,它是所有路由器事件的联合,所以当我们订阅它时,它显然会混淆打字稿!
因此,我们使用
is
关键字来缩小类型和资产的范围,以打字稿返回类型将是 NavigationEnd
在filter()中,我们说routingEvent是NavigationEnd。当我们订阅时,这会改变输出吗?如果是这样,为什么我们不能直接返回 true,因为我们实际上只是声明routingEvent 是 NavigationEnd?
Ans:不,TypeScript 只是一个开发层实体,意味着它辅助开发并且不会干扰返回值,其目的是帮助开发人员捕获错误并编写干净的代码,注意 TypeScript 会将代码转换为 JavaScript,我们当我们将它们转换为 javascript 时,一些运算符会转换为不同的结构
所以回答你的问题,打字稿不会转换任何东西,我们使用过滤器的原因是过滤掉事件,而且我们只有在这样做时才返回布尔条件
routingEvent instanceof NavigationEnd