在不同类型检查(tsconfig)上创建编译器错误

2024-05-28

有人可以解释为什么这不会引发错误吗?

interface A {
    id?: number;
}
const a:A = {
    id: 5
};
const testA: boolean = (a === 1); //works, but why?


interface B {
    id: number;
}
const b:B = {
    id: 5
};
const testB: boolean = (b === 1); //compiler error -> expected that also on A

让我们检查一下这种行为:

let foo: { foo?: number } = { foo: 1 };
foo = 1; // error, no common properties
foo === 1; // okay

在 TypeScript 2.4 及更高版本中,赋值失败,因为foo is a 弱型 http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html#weak-type-detection(所有属性都是可选的,例如Partial<Something>) 没有共同的属性number。根据结构兼容性的正常规则(TS2.4 之前),此分配应succeed,因为只要一个number没有any属性名为foo,在运行时没有不兼容...(1).foo is undefined, and undefined是你阅读时所期待的事情之一foo from {foo?: number}。但这是错误的潜在来源,因此 TS2.4 引入了弱类型检测来捕获它们;也就是说,语言使弱类型不兼容阻止可分配性.

然而,比较成功了,因为可比性弱类型不兼容性不会阻止。这两种类型仍然被认为具有可比性。为什么?好吧,我不确定动机是什么,但我可以看出它至少是故意的。有一段时间,有人推动更新模具TypeScript 规范 https://github.com/microsoft/TypeScript/blob/master/doc/spec.md。我认为他们已经放弃了这样的更新(语言变化太快,他们没有足够的资源来不断地研究规范,这样做的结果是,为了理解当前的语言,你需要继续阅读发行说明、GitHub 问题,甚至源代码),但我看到其中一个未合并的拉取请求,微软/TypeScript#17215 https://github.com/microsoft/TypeScript/pull/17215,提供了有关可比性的详细信息。具体来说 https://github.com/microsoft/TypeScript/pull/17215/commits/e2e20bd6f810dd210f641794ab6a46e0d98eb0a4#diff-a37bdfbd0d2f3627958003f87033871eR2396:

一个类型是否被认为是弱类型与两个类型是否具有可比性无关

那么就这样吧。可比性忽略了类型的弱点,因此您可以进行比较{foo?: number} with number。这是故意的,尽管再次不确定为什么。

我猜你(或其他人)提交了微软/TypeScript#36602 https://github.com/microsoft/TypeScript/issues/36602询问此事。如果我们想要改变这一点,这里要问的重要问题是:如果我们加强这一点,现实世界的 TypeScript 代码会破坏什么。如果数量很多,并且大多数损坏都没有捕获合法的错误,那么这种情况发生改变的可能性非常低。即使它只是在错误查找方面有所改进,它也可能会降低编译器性能太多,不值得。唯一确定的方法是 TS 团队同意考虑针对此更改的拉取请求。而且我并不在那个团队中所以????‍♂️。


最后,我们将之前的代码稍加修改进行对比,以确保我们理解非重叠弱类型、非重叠非弱类型和重叠弱类型之间的区别:

这是一个非重叠非弱类型:

let bar: { bar: number } = { bar: 1 };
bar = 1; // error, not assignable
bar === 1; // error, not comparable 

赋值和比较都失败;这些类型在结构上不兼容。这是一个重叠的弱类型:

let baz: { toFixed?(): string } = { toFixed: () => "" };
baz = 1; // okay
baz === 1; // okay

赋值和比较均成功;自从number has a toFixed()方法返回一个string, (出色地,Number有它,并且number被强迫Number当您访问其成员时)类型{toFixed?(): string}是一个弱类型,重叠number.


好的,希望这有助于理解这种行为。祝你好运!

Playground 代码链接 https://www.typescriptlang.org/play/#code/DYUwLgBAZg9jBcEDe04H5EDsCuBbARiAE4QC+EAvMqghAIxkDcAULDJfYxAPTcTFEYRADQRM7AMYxcuGJggAHQQuJgAliADOrOJQpU6XXhBgBrAIYBPZs1CR85oohQOnYvIRLkqLx4gakLK4chjx8AkKi4pDmmppqAOaY5vigzMH6BkbhRIIiYjCQUrgKjimgEDZ2EA4AXs4QYDAAYmoAHiAAJmgAFACUiJpgRGqYCWQcKE2tHZ2I-ZQAfBAARCtM6ea1IdkmFtZ1ellhe1Y2QA

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在不同类型检查(tsconfig)上创建编译器错误 的相关文章

随机推荐

  • Sublime Text 是否支持 Ruby API(自动完成)?

    如何获取可用于某些对象或类的方法列表 如下所示 Sublime Text 有针对 Ruby 的此功能吗 像这样https github com BoundInCode Display Functions https github com B
  • 如何找到 emacs 中定义键绑定的位置?

    Somehow shift m是必然的Meta在 emacs 中键入 现在我无法输入任何以M like Mock 我想找出为什么会发生这种情况 或者是哪个包导致了这种情况 有一个问题 https stackoverflow com ques
  • 如何在 Plesk Obsidian 上为 Node.js 管理器添加新的 NodeJS 版本?

    Since Plesk 黑曜石 v18 x 它不像以下程序那样工作这个答案 Plesk Onyx https stackoverflow com a 46846077 10824494现在我无法添加新版本的 NodeJS plesk sbi
  • GCC:如何在 MCU 上完全禁用堆使用?

    我有一个在基于 ARM Cortex M 的 MCU 上运行并用 C 和 C 编写的应用程序 我用gcc and g 编译它并希望完全禁用任何堆使用 在 MCU 启动文件中 堆大小已设置为 0 除此之外 我还想禁止代码中意外使用堆 换句话说
  • Docker 容器中的并行代码执行

    我有一个通过 URLslist 抓取数据的脚本 该脚本在 docker 容器中执行 我想在多个实例中运行它 例如 20 个 为此 我想使用docker compose scale worker 20并将 INDEX 传递给每个实例 以便脚本
  • FreeBSD 上 valgrind 的限制

    我一直在尝试使用 valgrind 查找一些可疑的内存错误 在被分析的程序甚至到达我想要分析的点之前 它会因为对 mmap 的调用开始失败而退出 当不在 valgrind 下时 这些调用会成功 valgrind 下可能的文件映射 映射内存数
  • Laravel Redis 配置

    我目前正在使用 Laravel 和 Redis 创建一个应用程序 几乎一切都工作正常 我按照文档中的说明扩展了身份验证 用户可以订阅 登录 注销 我可以创建内容 所有内容都存储在 Redis 中 但我有一个问题 我无法运行 php arti
  • 表格固定标题和第一列 css/html

    我有一个包含大量行和列的表 但我想固定标题和第一列 这是我需要的图片 只有粉色部分必须水平和垂直滚动 但其他部分在滚动过程中必须保持可见 我的表位于 div 中 首先 我应该使用一张桌子还是四张桌子 蓝色桌子 红色桌子 绿色桌子和粉色桌子
  • C++ 中的“int”默认是“signed long int”吗?

    Is int默认情况下signed long int in C 它是否依赖于平台和 或编译器 如果是这样 怎么办 EDIT 以下任何一项是否保证是重复的 signed short int signed int signed long int
  • 为什么我不能在 cygwin 中使用 $SVN_EDITOR 环境变量?

    我一定是错过了一些愚蠢的事情 当我使用 m 选项时它工作正常 echo SVN EDITOR emacs svn commit test py svn Commit failed details to follow svn Could no
  • 读取大文件并制作字典

    我有一个大文件 我需要读取它并从中制作字典 我希望这一切能够尽可能快 然而我的Python代码太慢了 这是一个显示问题的最小示例 首先制作一些假数据 paste lt seq 20000000 lt seq 2 20000001 gt la
  • C# - Visual Studio 中的 System.OutOfMemoryException

    我遇到问题 当我右键单击 Visual Studio 中的主窗体并转到 视图设计器 时 出现错误 它说 引发了 System OutOfMemoryException 类型的异常 堆栈跟踪 at System Reflection Asse
  • 如何解决Android错误类型3?

    下面是我在项目中使用的清单格式 但是每当我尝试运行模拟器时 我都会收到下面提到的错误 请给我一个解决该错误的准确解决方案 工具信息 Android studio Nexus S API 22 android 5 1 1 我的清单文件格式
  • YouTube 视频出现 Phantom JS 错误

    Phantom JS 版本 1 9 1 恶作剧版本 1 3 0 从今天开始 YouTube 嵌入视频在运行 javascript 测试时会出现 poltergeist 错误 我的 YouTube 代码只是默认的嵌入 YouTube 代码 这
  • 设置绝对仓位和保证金

    我想设置一个元素的position to absolute并有一个margin bottom 但似乎margin bottom没有效果 HTML div div CSS container border 1px solid red posi
  • Mapbox 打字稿

    通过关注这个项目 我成功地让 Leaflet 与 Angular 2 和 Webpack 一起工作 Angular 2 传单启动器 https github com haoliangyu angular2 leaflet starter 我
  • 如何以编程方式创建选项卡栏

    大家好 我有基于导航的应用程序 其中我也需要在视图之一中实现选项卡栏 在一个视图中我需要 5 个选项卡 有人可以建议我以编程方式创建选项卡栏吗 每个选项卡应导航到另一个 xib 建议始终受到赞赏 问候 以下是 Apple 提供的用于以编程方
  • 如何使用最小起订量模拟私有只读 IList 属性

    我试图嘲笑这个列表 private readonly IList
  • 如何从 GridView TemplateColumn 单击触发 UpdatePanel?

    我有以下情况 我的所有控件都在页面上的更新面板上 这些控件之一是 GridView 该 GridView 在标题模板字段上包含一个复选框 以进行全部选中 autopostback 是 true 但是当检查更改时 没有任何更改 更新面板会触发
  • 在不同类型检查(tsconfig)上创建编译器错误

    有人可以解释为什么这不会引发错误吗 interface A id number const a A id 5 const testA boolean a 1 works but why interface B id number const