This is known as a const assertion https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions. A const
assertion tells the compiler to infer the narrowest* or most specific type it can for an expression. If you leave it off, the compiler will use its default type inference behavior, which will possibly result in a wider or more general type.
请注意,它称为“断言”而不是“强制转换”。在 TypeScript 中通常要避免使用“cast”这个术语;当人们说“cast”时,他们通常暗示某种可以在运行时观察到的效果,但是 TypeScript 的类型系统,包括类型断言和const
断言,完全是erased https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types来自发出的 JavaScript。所以完全没有区别在运行时在使用的程序之间as const
和一个没有。
但在编译时,存在明显的差异。让我们看看当你离开时会发生什么as const
在上面的例子中:
const args = [8, 5];
// const args: number[]
const angle = Math.atan2(...args); // error! Expected 2 arguments, but got 0 or more.
console.log(angle);
编译器看到const args = [8, 5];
并推断出类型number[]
。这是一个由零个或多个类型元素组成的可变数组number
。编译器不知道how many or which元素有。这样的推论大体上是合理的;通常,数组内容需要以某种方式进行修改。如果有人想写args.push(17)
or args[0]++
,他们会对某种类型感到满意number[]
.
不幸的是下一行,Math.atan2(...args)
,导致错误。这Math.atan2()
函数恰好需要两个数字参数。但编译器都知道args
是它是一个数字数组。它完全忘记了有两个元素,因此编译器抱怨您正在调用Math.atan2()
当它只需要两个时,使用“0个或多个”参数。
将其与代码进行比较as const
:
const args = [8, 5] as const;
// const args: readonly [8, 5]
const angle = Math.atan2(...args); // okay
console.log(angle);
现在编译器推断args
属于类型readonly [8, 5]
... a readonly tuple https://www.typescriptlang.org/docs/handbook/2/objects.html#readonly-tuple-types其值正是数字8
and 5
以该顺序。具体来说,args.length
已知正是2
由编译器。
这对于下一行来说就足够了Math.atan2()
上班。编译器知道Math.atan2(...args)
是相同的Math.atan2(8, 5)
,这是一个有效的调用。
再说一遍:在运行时,没有任何区别。两个版本都记录1.0121970114513341
到控制台。但const
与静态类型系统的其余部分一样,断言并不意味着在运行时产生影响。相反,它们让编译器更多地了解intent的代码,并且可以更准确地辨别正确代码和错误之间的区别。
* This isn't strictly true for array and tuple types; a readonly
array or tuple is technically wider than a mutable version. A mutable array is considered a subtype of a readonly
array; the former is not known to have mutation methods like push()
while the latter does.