为什么 Typescript 允许子类型化?

2023-12-05

根据文档,“TypeScript 中的类型兼容性基于结构子类型”。所以这是可能的:

type Person: {
  name: string;
}

const developer = {
  name: 'Joe',
  language: 'Typescript',
}

// this is ok because Person is a subtype of typeof developer
const otherDeveloper: Person = developer; // who writes code like that?!

这会产生很多后果,其中之一是使用 Object.keys 时会丢失类型信息:

// "keys" type is array of strings not `name` literal as this would be of course wrong because in runtime "keys" is ['name', 'language']
const keys = Object.keys(otherDeveloper); 

所以我试图在 TS 文档中找到这种子类型的原因,正如他们所承诺的,但我找不到

TypeScript 允许不合理行为的地方都经过仔细考虑,在本文档中,我们将解释这些情况发生的位置以及背后的动机场景。

这可能对我有帮助的唯一地方是需要较窄类型对象的函数,例如:

function getName(person: Person) {
  return person.name;
}

getName(developer); // works fine because of subtyping

如果在这种情况下必须使用强制转换,我个人并不认为有什么大问题:

getName(developer as Person);

还有其他我可能遗漏的例子吗?


Typescript 使用结构类型的原因是 JS 是鸭子类型的。

因此,您可以在 JS 中执行上面编写的操作,理想情况下,您可以在 TS 中以更类型安全的方式执行此操作。 Javascript不关心对象声明的类型,JS中没有这个概念,它只关心对象在运行时具有的属性。因此任何对象都可以传递到你的getName函数,只要 name 属性存在,该函数就可以正确运行。

此外,由于 JS 具有不属于特定类的对象文字,因此很难在任何地方显式指定继承关系。明确类型关系会降低 TS 对 JS 开发人员的吸引力。在结构类型系统下,类型大部分都可以工作,您可以从中获得很多好处,而不必非常明确。

有一些方法可以通过使用私有属性来绕过结构类型并模仿打字稿中的规范类型(ex)或使用品牌类型(ex)

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

为什么 Typescript 允许子类型化? 的相关文章

随机推荐

  • 自动解锁 Windows 用户会话

    最近 我一直在开发 CredentialProvider 以便自动解锁 触发器可以是任何事件 例如计时器结束 Windows Vista 或更新版本 用户会话 为此 我阅读了一些关于该主题的有用文章 即 GINA 和这种新架构之间的变化 h
  • 使用 C/C++ 高效地反序列化由浮点数、标记和空行组成的字符串

    我有类似于以下内容的大字符串 some text token 24 325973 20 638823 1 964366 0 753947 1 290811 3 547422 0 813014 3 547227 0 472015 3 7233
  • cv::RotatedRect 中非零像素的数量

    正如标题所说 我试图找到 cv Mat 的某个区域 即 RotatedRect 内 的非零像素数 对于常规矩形 可以简单地在 ROI 上使用 countNonZeroPixels 然而 ROI 只能是规则的 非旋转的 矩形 另一个想法是绘制
  • 带有 IntelliJ 和 Tomcat 的 Java-ee REST 服务器

    我正在尝试使用 Java ee 实现 REST 服务器 API 如下所示this教程 我使用 Tomcat 而不是 Glassfish 我可以开发一个servlet WebServlet name hello urlPatterns pub
  • Java HTTP 服务器

    我想在本地实现一个 Java HTTP 服务器 我的意思是服务器计算机将在我的控制之下 我预计向其发送请求的客户端不会超过 20 个 我想知道如何去做 我应该使用 J2EE servlet 容器 例如 Apache Tomcat 吗 我可以
  • 如何在重绘时保存先前绘制到画布上的对象?

    每次重绘 SurfaceView 时 之前绘制的内容都会被擦除 如何保存它们的状态 以便我的循环将新对象添加到屏幕上而不删除旧对象 用一个画Bitmap Bitmap mDrawBitmap Canvas mBitmapCanvas Pai
  • 如何从命令行中的脚本运行函数?

    我有一个具有一些功能的脚本 我可以直接从命令行运行其中一个函数吗 像这样的东西吗 myScript sh func 好吧 虽然其他答案是正确的 你当然可以做其他事情 如果你有权访问 bash 脚本 你可以修改它 然后简单地将特殊参数放在最后
  • 超时期限未过,但仍然超时(参见代码)?

    好的 在大约 3 4 分钟的搅拌后 我不断收到此错误 Timeout expired The timeout period elapsed prior to completion of the operation or the server
  • 如何在空手道功能中循环数组值

    我正在尝试循环空手道功能文件中的数组值 在Feature1 feature Scenario1中 我在数组 UUID1 UUID2 UUID3 中有一些值 我想调用另一个功能文件 Feature2 feature 有一个代码来调用DELET
  • QUnit,断言不行吗?

    抱歉 如果这是显而易见的 但是如果我们想断言某个方法返回 false QUnit 中是否有 notOK 或等效函数 我看不出有什么办法可以否定 OK文档 I tried ok 但这没有用 你可以使用 ok method expected t
  • 在通过 HomeBrew 安装的 macOS 上设置 ANTLR 的 CLASSPATH

    下列的这个问题 我通过 HomeBrew 安装了 ANTLR brew install antlr 它安装在 usr local Cellar antlr
  • 遍历组并为每个 R 创建绘图

    我正在尝试映射 循环鸢尾花数据集中的物种列 为每个物种创建一个图 下面的脚本返回三个图表 但所有图表都绘制了相同的数据 并且不按物种划分 地图函数似乎忽略了species list 只查看整个数据帧 一直在尝试不同的方法 但无法使任何工作发
  • Swift 3 和 Swift 4 中的 WebService API 方法?

    我是新来的SwiftiOS 和我想在单独的类中创建一个单独的方法 例如NSObject 的 Web 服务 以便我可以在任何 ViewController 中使用它并解析任何类型的JSON响应使用NSURLSession and Alamof
  • 用于自动化 ncurses 类型 telnet 会话的跨平台解决方案

    背景 我在网络和电信领域的部分工作涉及当传统硬件无法在其他接口中提供简单的解决方案时自动执行 telnet 会话 许多旧设备只能通过工艺端口 RS 232 串行端口 SNMP 或 Telnet 进行访问 有时 telnet 是访问特定信息的
  • 将数组从 JSON 文件导入到 Typescript 文件中

    我有一个 JSON 文件 其中包含一个数组对象 如下所示 VergiNo XXXXXXX VergiNo YYYYYY VergiNo ZZZZZZ 我将此 JSON 文件导入到我的 Typescript 文件中 import as fir
  • PHP 会话变量与局部变量互换?

    我遇到了一个关于 php ini 中的会话变量和局部变量的非常奇怪的问题 我试图弄清楚我是否不了解 php 中的会话 或者这是否是我的主机使用的 php 版本的问题 这是一个非常简单的代码来演示这个奇怪的问题 session start v
  • C 和 C++ 中 += 的结果是什么?

    我有以下代码 include
  • 如何区分bool和int

    我有一个清单 它包含不同类型的值 例如 1 2 3 a False 0 5 0 3 任务是将所有零移动到列表的末尾 它应该看起来像这样 1 2 3 a False 5 3 0 0 如何区分布尔值False from 0 我正在尝试将它们与以
  • 1 viewmodel多条路线:生命周期

    我想要有几个不同的路线指向相同的视图 视图模型 并且我已经成功地实现了这一点 route formulation moduleId formulation title Formulation nav 6 route fabrication
  • 为什么 Typescript 允许子类型化?

    根据文档 TypeScript 中的类型兼容性基于结构子类型 所以这是可能的 type Person name string const developer name Joe language Typescript this is ok b