简体   繁体   English

typescript 中的多个类型断言

[英]Multiple type assertions in typescript

I was looking at the source code of an angular repository and stumbled upon a line of code that uses multiple type assertions.我在查看 angular 存储库的源代码时偶然发现了一行使用多种类型断言的代码。

The code looks kinda like this one, it uses 2 type assertion: unknown and Record<string, unknown>代码看起来有点像这个,它使用 2 种断言: unknownRecord<string, unknown>

 (window as unknown as Record<string, unknown>)['ResizeObserver'] 

Here's the link to the actual file.这是实际文件的链接

What does multiple assertions actually mean?多重断言实际上意味着什么?

You use type assertions too narrow down the type of a value so you can use it.您使用类型断言过于缩小了值的类型,因此您可以使用它。 This is known as double assertion .这称为双重断言

The assertion from type S to T succeeds if either S is a subtype of T or T is a subtype of S.如果 S 是 T 的子类型或 T 是 S 的子类型,则从类型 S 到 T 的断言成功。

Since we are unsure of the shape of the window object we cannot be sure that we can check that the ResizeObserver property has a value other than null.由于我们不确定window object 的形状,因此我们无法确定是否可以检查ResizeObserver属性是否具有 null 以外的值。

So we can cast it to unknown, because anything can be assigned to unknown.所以我们可以将它转换为 unknown,因为任何东西都可以赋值给 unknown。

And because anything can be assigned to unknown we now have free range to shape the object how we want in order to satisfy our conditional.因为任何东西都可以分配给未知,我们现在可以自由地塑造 object 来满足我们的条件。 Since we need to check that a properties value is not null, we can simply use Record<string, unknown>由于我们需要检查属性值是否不是 null,我们可以简单地使用Record<string, unknown>

We end up with:我们最终得到:

(window as unknown as Record<string, unknown>)['ResizeObserver'] != null

By doing this we can write a conditional to check that the ResizeObserver property is not null no matter what shape the window object has.通过这样做,我们可以编写一个条件来检查ResizeObserver属性是否不是 null,无论window object 具有什么形状。

You can think of as like an operator (left associative):你可以把它想象as一个运算符(左结合):

((window as unknown) as Record<string, unknown>)['ResizeObserver'] 

So here, it casts window to unknown which is valid.所以在这里,它将 window 转换为有效的unknown It's upcasting from the type of window to unknown .它从window类型向上转换为unknown

Then we downcast from unknown to Record<string, unknown> , which is also perfectly valid.然后我们从unknown向下转换为Record<string, unknown> ,这也是完全有效的。

But if we do only window as Record<string, unknown> , we get an error.但是,如果我们仅window as Record<string, unknown> ,则会出现错误。 Window does not have anything in common with Record<string, unknown> ! Window 与Record<string, unknown>没有任何共同之处!

Here's an extra example of as to demonstrate that it's just a simple operator:这是as的一个额外示例,以证明它只是一个简单的运算符:

42 as number as number as number

(((42 as number) as number) as number)

You can think of it like this:你可以这样想:

VALID
       unknown
         ^ \
        /   \
Window /     > Record<string, unknown>
INVALID
Window ------> Record<string, unknown>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM