typescript - "as const"在 TypeScript 中是什么意思,它的用例是什么?

标签 typescript type-assertion

我对 as const 感到困惑 throw 。我检查了一些文件和视频,但没有完全理解。
我关心的是 as const在下面的代码中是什么意思,使用它有什么好处?

const args = [8, 5] as const;
const angle = Math.atan2(...args);
console.log(angle);

最佳答案

这被称为 const assertion . A const断言告诉编译器为表达式推断最窄的*或最具体的类型。如果您不使用它,编译器将使用其默认类型推断行为,这可能会导致更广泛或更通用的类型。
请注意,它被称为“断言”而不是“强制转换”。在 TypeScript 中通常要避免使用术语“cast”;当人们说“cast”时,他们通常暗示某种可以在运行时观察到的效果,但是 TypeScript 的类型系统,包括类型断言和 const断言,完全是erased来自发出的 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 类型元素的可变数组.编译器不知道有多少或哪些元素。这样的推断通常是合理的;通常,数组内容旨在以某种方式进行修改。如果有人想写 args.push(17)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] ... readonly tuple其值正是数字 85以该顺序。具体来说,args.length已知正是 2由编译器。
这对于下一行 Math.atan2() 来说已经足够了上类。编译器知道 Math.atan2(...args)Math.atan2(8, 5) 相同,这是一个有效的调用。

再说一遍:在运行时,没有任何区别。两个版本的日志 1.0121970114513341到控制台。但是const与静态类型系统的其余部分一样,断言并不意味着在运行时产生影响。相反,它们让编译器更多地了解代码的意图,并且可以更准确地分辨正确代码和错误之间的区别。
Playground link to code

* 对于数组和元组类型,严格来说并非如此; readonly数组或元组在技术上比可变版本更宽。可变数组被认为是 readonly 的子类型大批;前者不知道有像 push() 这样的变异方法。而后者确实如此。

关于typescript - "as const"在 TypeScript 中是什么意思,它的用例是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66993264/

相关文章:

json - 如何提示我无法控制的函数类型?

typescript - 使用 Jasmine 监视私有(private)变量的属性/函数

javascript - Angular 应用程序中的 Angular 元素在优化时会产生无限重新加载问题

angular - 如何加快选择框的性能?

go - 类型断言是处理接口(interface)时返回结构指针的唯一方法吗?

typescript - 我可以在不通过断言强制类型的情况下修复此 typescript 编译器错误吗?

typescript - 如何使用 LatestFrom 从 rxjs 6 键入数组映射参数

angular - 类型 'Observable<User | null>' 不可分配给类型 'Observable<User>'

typescript - 将使用 Typescript 中的 --strictNullChecks 从 DB 或 API 接收异步数据的变量类型?

go - 在 Go 中是否有一种惯用的方法来通过类型断言的接口(interface)进行索引?