理解 typecript 中的“is”关键字

问题描述 投票:0回答:2

我想了解我在 Typescript/Angular 中看到的特定模式,如下所示:

this.subscription = this.router.events
    .pipe(
        filter((routingEvent: any): routingEvent is NavigationEnd => routingEvent instanceof NavigationEnd),

据我了解,“is”关键字缩小了type的范围。这意味着 Angular 的 RouterEvent 类变成了它的子类

NavigationEnd
。然后我们检查
routingEvent
是否属于实例
NavigationEnd
。我有两个问题:

  • 如果我们使用“map()”并说
    routingEvent is NavigationEnd
    不是更高效吗?
  • filter()
    中,我们说过
    routingEvent is NavigationEnd
    。当我们订阅时,这会改变输出吗?如果是这样,为什么我们不能直接
    return true
    因为我们实际上只是声明了
    routingEvent is NavigationEnd

如果这些问题有缺陷,请原谅我,因为我是 Typescript 的新手,但如果有人可以帮助我,那就太好了。

angular typescript rxjs
2个回答
0
投票

打字稿中的

is
关键字用于描述 谓词

谓词用于用户定义的类型防护。

当你有

(routingEvent: any): routingEvent is NavigationEnd => routingEvent instanceof NavigationEnd),

-1
投票

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 时,一些运算符会转换为不同的结构

Typescript 游乐场示例

所以回答你的问题,打字稿不会转换任何东西,我们使用过滤器的原因是过滤掉事件,而且我们只有在这样做时才返回布尔条件

routingEvent instanceof NavigationEnd

© www.soinside.com 2019 - 2024. All rights reserved.