”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > TypeScript 严格类型 - 部分完整静态类型

TypeScript 严格类型 - 部分完整静态类型

发布于2024-08-06
浏览:342

TypeScript strictly typed - Part full static types

在本系列文章的前一部分中,我们讨论了安全可为空性。

现在我们将解释并解决 TypeScript 默认行为的第三个问题,也是最后一个问题:动态类型的剩余部分

我们将涵盖:

  • 动态类型的残余
  • 实际平等检查
  • 条件中没有隐式转换
  • 条件简写
  • 字符串和数字不能混合

动态类型的残余

TypeScript 应该是一个“静态类型检查器”,与 JavaScript 不同,JavaScript 中的类型是深度动态的。

但在本系列文章的前一部分中,我们还解释了 TypeScript 是作为 JavaScript 的超集构建的。

所以问题是:JavaScript 动态类型系统的某些部分仍然保留在 TypeScript 中。因此,我们将解释如何抑制这些剩余行为以实现完全静态类型

实际平等检查

  • ESLint: eqeqeq
  • 生物群落:可疑.noDoubleEquals(推荐)

这个问题最好的例子是相等性检查。在 JavaScript 中,== 并不完全是相等检查,而是等价检查:

1 == "1"; // true

尽管类型不同,但一些转换规则会起作用,因此 JavaScript 能够比较值。它可能会导致很多错误,因为规则细节很难记住,有时很奇怪,并且在所有动态语言(例如 PHP)中并不完全相同。

这些等价性检查仅在 JavaScript 等动态类型语言中才有意义。从我们决定使用 TypeScript 的那一刻起,只应使用实际的相等检查(类型和值)。

1 === "1"; // false

eqeqeq lint 规则强制执行它。

来自 Java、C# 或 Rust 等语言的人应该特别小心这个问题,因为 JavaScript 或 TypeScript 中的 == 与这些语言中的含义不同。在 JavaScript 和 TypeScript 中,需要第三个 = 才能实现相同的行为。

条件中没有隐式转换

  • ESLint:@typescript-eslint/strict-boolean-expressions
  • 生物群落:缺少规则

认为现在情​​况安全吗?不幸的是不是,因为转换可以是隐式的:

let tax: number | undefined = 0;

if (tax) {
  console.log("Process payment");
}
if (!tax) {
  throw new Error();
}

上面的例子相当于:

let tax: number | undefined = 0;

if (tax == true) {
  console.log("Process payment");
}
if (tax == false) {
  throw new Error();
}

如您所见,存在隐式 ==,因此仍然会发生转换:0 不等于 true,它等于 false。因此,尽管税费是有效值,它也会出错。

严格布尔表达式 lint 规则不允许此类隐式条件,并强制执行实际检查:

let tax: number | undefined = 0;

if (tax !== undefined) {
  console.log("Process payment");
}
if (tax === undefined) {
  throw new Error();
}

对于习惯了 JavaScript 快速条件的人来说,这可能是最繁琐的规则之一,但从长远来看,这只是在 Java、C# 或 Rust 等其他语言中执行操作的正常方法。

如配置部分所示,禁用allowNumber和allowString子选项对于避免所有错误非常重要。

唯一允许的例外是对象和数组:这些情况是安全的,因为与字符串和数字相反,它们没有假值。所以下面的还是可以的:

let movie: Movie | undefined;
if (movie) {}
if (!movie) {}

注意:switch 语句已经安全,因为它们在内部使用 ===。

条件简写

  • ESLint:@typescript-eslint/prefer-nullish-coalescing(在风格类型检查中)
  • 生物群落:缺少规则

严格布尔表达式 lint 规则注意条件检查是类型安全的,但除了 if:
之外,还有其他条件语法

const movieRating = userRating || 5;

// Which is a shorter version of:
const movieRating = userRating == true ? userRating : 5;

如果用户评分为 0,则 0 相当于 false,因此评分将为 5 而不是 0。

现代 JavaScript 可以避免这种情况:

const movieRating = userRating ?? 5;

// Which is a shorter version of:
const movieRating = userRating !== undefined && userRating !== null
  ? userRating
  : 5;

它可以通过prefer-nullish-coalescing lint 规则强制执行。

注意 ??不应在任何地方使用: ||在使用布尔值时仍然相关。

字符串和数字不能混合

  • ESLint:
    • 首选模板
    • @typescript-eslint/restrict-plus-operands(在推荐类型检查中)
    • @typescript-eslint/restrict-template-expressions(在推荐类型检查中)
  • 生物群落:
    • style.useTemplate(推荐)
    • 缺少其他规则

在 JavaScript 中,运算符既可用于数字的数学加法,也可用于字符串连接。它会导致错误。

"There is "   3   1   "Matrix movies"; // 31
"There is "   (3   1)   "Matrix movies"; // 4

运算符应保留用于数学加法。或者至少,它应该仅用于相同类型的数据,这是restrict-plus-operands lint 规则强制执行的。

现代 JavaScript 中的模板字符串应该用于字符串连接,prefer-template lint 规则强制执行:

const movie = `Everything everywhere all at once`;
`${movie} is the best movie!`;

相反,模板字符串中只能使用字符串,这是restrict-template-expressions lint 规则强制执行的。

如果混合类型是实际想要的,则转换应该是显式的:

const total = 3;
`There is ${total.toFixed()} Matrix movies`;

注意模板字符串可以嵌套:

const total = 3;
`There is ${total.toFixed()} Matrix movie${total > 1 ? "s" : ""}`;

结论

这是本系列文章的结尾。您可以关注我的帐户(本页右上角的按钮),了解有关 TypeScript 或 Angular 等其他主题的其他帖子何时发布。

您想联系我?摘要中提供了说明。

版本声明 本文转载于:https://dev.to/cyrilletuzi/typescript-strictly-typed-part-4-full-static-types-8bc?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在JTable中维护jtable单元格渲染后,在JTable中,在JTable中实现自定义单元格渲染和编辑功能可以增强用户体验。但是,至关重要的是要确保即使在编辑操作后也保留所需的格式。在设置用于格式化“价格”列的“价格”列,用户遇到的数字格式丢失的“价格”列的“价格”之后,问题在设置自定义单元格...
    编程 发布于2025-07-13
  • `console.log`显示修改后对象值异常的原因
    `console.log`显示修改后对象值异常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    编程 发布于2025-07-13
  • 在PHP中如何高效检测空数组?
    在PHP中如何高效检测空数组?
    在PHP 中检查一个空数组可以通过各种方法在PHP中确定一个空数组。如果需要验证任何数组元素的存在,则PHP的松散键入允许对数组本身进行直接评估:一种更严格的方法涉及使用count()函数: if(count(count($ playerList)=== 0){ //列表为空。 } 对...
    编程 发布于2025-07-13
  • C++成员函数指针正确传递方法
    C++成员函数指针正确传递方法
    如何将成员函数置于c [&& && && && && && && && && && &&&&&&&&&&&&&&&&&&&&&&&华仪的函数时,在接受成员函数指针的函数时,要在函数上既要提供指针又可以提供指针和指针到函数的函数。需要具有一定签名的功能指针。要通过成员函数,您需要同时提供对象指针(此...
    编程 发布于2025-07-13
  • 如何在GO编译器中自定义编译优化?
    如何在GO编译器中自定义编译优化?
    在GO编译器中自定义编译优化 GO中的默认编译过程遵循特定的优化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    编程 发布于2025-07-13
  • 将图片浮动到底部右侧并环绕文字的技巧
    将图片浮动到底部右侧并环绕文字的技巧
    在Web设计中围绕在Web设计中,有时可以将图像浮动到页面右下角,从而使文本围绕它缠绕。这可以在有效地展示图像的同时创建一个吸引人的视觉效果。 css位置在右下角,使用css float and clear properties: img { 浮点:对; ...
    编程 发布于2025-07-13
  • 如何使用Python有效地以相反顺序读取大型文件?
    如何使用Python有效地以相反顺序读取大型文件?
    在python 中,如果您使用一个大文件,并且需要从最后一行读取其内容,则在第一行到第一行,Python的内置功能可能不合适。这是解决此任务的有效解决方案:反向行读取器生成器 == ord('\ n'): 缓冲区=缓冲区[:-1] ...
    编程 发布于2025-07-13
  • 如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    使用http request 上传文件上传到http server,同时也提交其他参数,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    编程 发布于2025-07-13
  • 用户本地时间格式及时区偏移显示指南
    用户本地时间格式及时区偏移显示指南
    在用户的语言环境格式中显示日期/时间,并使用时间偏移在向最终用户展示日期和时间时,以其localzone and格式显示它们至关重要。这确保了不同地理位置的清晰度和无缝用户体验。以下是使用JavaScript实现此目的的方法。方法:推荐方法是处理客户端的Javascript中的日期/时间格式化和时...
    编程 发布于2025-07-13
  • 解决Spring Security 4.1及以上版本CORS问题指南
    解决Spring Security 4.1及以上版本CORS问题指南
    弹簧安全性cors filter:故障排除常见问题 在将Spring Security集成到现有项目中时,您可能会遇到与CORS相关的错误,如果像“访问Control-allo-allow-Origin”之类的标头,则无法设置在响应中。为了解决此问题,您可以实现自定义过滤器,例如代码段中的MyFi...
    编程 发布于2025-07-13
  • 左连接为何在右表WHERE子句过滤时像内连接?
    左连接为何在右表WHERE子句过滤时像内连接?
    左JOIN CONUNDRUM:WITCHING小时在数据库Wizard的领域中变成内在的加入很有趣,当将c.foobar条件放置在上面的Where子句中时,据说左联接似乎会转换为内部连接。仅当满足A.Foo和C.Foobar标准时,才会返回结果。为什么要变形?关键在于其中的子句。当左联接的右侧值...
    编程 发布于2025-07-13
  • 表单刷新后如何防止重复提交?
    表单刷新后如何防止重复提交?
    在Web开发中预防重复提交 在表格提交后刷新页面时,遇到重复提交的问题是常见的。要解决这个问题,请考虑以下方法: 想象一下具有这样的代码段,看起来像这样的代码段:)){ //数据库操作... 回声“操作完成”; 死(); } ?> ...
    编程 发布于2025-07-13
  • \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    答案: 在大多数现代编译器中,while(1)和(1)和(;;)之间没有性能差异。编译器: perl: 1 输入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    编程 发布于2025-07-13
  • Java为何无法创建泛型数组?
    Java为何无法创建泛型数组?
    通用阵列创建错误 arrayList [2]; JAVA报告了“通用数组创建”错误。为什么不允许这样做?答案:Create an Auxiliary Class:public static ArrayList<myObject>[] a = new ArrayList<myO...
    编程 发布于2025-07-13

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3