在 TypeScript 中,可以在没有“new”关键字的情况下使用类吗?

2024-05-18

TypeScript 是包含类型的 ES6 Javascript 超集。可以使用以下方式声明一个类class关键字并使用实例化new关键字与 Java 中的关键字类似。

我想知道 TypeScript 中是否有任何用例可以在不使用new关键词。

我问的原因是因为我想知道,假设我有一个名为Bob,我可以假设任何实例Bob实例化为new Bob().


默认情况下,Typescript 可以防止这种情况发生,因此如果您这样做:

class A {}
let a = A();

你会得到一个错误:

类型值typeof A不可调用。你的意思是包括 '新的'?

然而,有些对象可以在不使用new关键字,基本上都是原生类型。
如果您查看 lib.d.ts,您可以看到不同构造函数的签名,例如:

字符串构造函数 https://github.com/Microsoft/TypeScript/blob/master/lib/lib.d.ts#L445:

interface StringConstructor {
    new (value?: any): String;
    (value?: any): string;
    ...
}

数组构造函数 https://github.com/Microsoft/TypeScript/blob/master/lib/lib.d.ts#L1243:

interface ArrayConstructor {
    new (arrayLength?: number): any[];
    new <T>(arrayLength: number): T[];
    new <T>(...items: T[]): T[];
    (arrayLength?: number): any[];
    <T>(arrayLength: number): T[];
    <T>(...items: T[]): T[];
    ...
}

正如你所看到的,无论有没有演员,总是有相同的演员new关键词。
如果您愿意,当然可以模仿这种行为。

重要的是要理解,虽然 typescript 会检查以确保这种情况不会发生,但 javascript 不会检查,因此如果有人编写将使用您的代码的 js 代码,他可能会忘记使用new,所以这种情况还是有可能的。

很容易检测到这种情况是否在运行时发生,然后按照您认为合适的方式处理它(抛出错误,通过使用返回实例来修复它new并记录下来)。
这是一篇讨论它的帖子:创建实例而不使用 new https://muffinresearch.co.uk/js-create-instances-without-new/(普通 js),但 tl;dr 是:

class A {
    constructor() {
        if (!(this instanceof A)) {
            // throw new Error("A was instantiated without using the 'new' keyword");
            // console.log("A was instantiated without using the 'new' keyword");

            return new A();
        }
    }
}

let a1 = new A(); // A {}
let a2 = (A as any)(); // A {}

(操场上的代码 https://www.typescriptlang.org/play/#src=class%20A%20%7B%0D%0A%09constructor()%20%7B%0D%0A%09%09if%20(!(this%20instanceof%20A))%20%7B%0D%0A%09%09%09return%20new%20A()%3B%0D%0A%09%09%7D%0D%0A%09%7D%0D%0A%7D%0D%0A%0D%0Alet%20a1%20%3D%20new%20A()%3B%20%2F%2F%20A%20%7B%7D%0D%0Alet%20a2%20%3D%20(A%20as%20any)()%3B%20%2F%2F%20A%20%7B%7D)


Edit

据我所知,不可能让编译器理解这一点A可以在没有new关键字而不强制转换它。
我们可以做得比把它投射到更好一点any:

interface AConstructor {
    new(): A;
    (): A;
}

let a2 = (A as AConstructor)(); // A {}

我们不能做那些正在做的事情的原因是(即)Array in lib.d.ts:

interface Array<T> {
    ...
}

interface ArrayConstructor {
    ...
}

declare const Array: ArrayConstructor;

他们在这里使用吗Array一次作为类型,一次作为值,但类既是类型又是值,因此尝试执行此技巧将以:

重复的标识符“A”

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

在 TypeScript 中,可以在没有“new”关键字的情况下使用类吗? 的相关文章

随机推荐

  • 传递 Stack 中两个小部件之间的所有手势

    我正在开发一个应用程序 在地图上显示标记 如下所示 它的工作方式是标记在地图小部件 上方 呈现为Stack 我的问题是 目前 标记 吸收 用于控制下方地图的手势 如果手势在标记上开始 因此我想知道 有没有办法在堆栈中的两个小部件之间传递所有
  • 在故事板中的视图控制器之间滑动手势

    我希望添加左右滑动手势来在视图控制器之间进行更改 这是否可能 并且有没有一种简单的方法可以在故事板中执行此操作 谢谢 故事板允许您在两个视图控制器之间设置 Segues 我想说首先在视图之间附加 Segues 给它一个标识符 然后使用类似的
  • 分发内部业务 IOS 应用程序

    我遇到了 IOS 应用程序分发的一个令人困惑的部分 因此 我需要简单细分一下我的限制 即仅将我的应用程序分发给我的员工 同事或任何被视为 内部 的人 这是表明我不希望该应用程序出现在应用程序商店中的另一种方式 我的情况是我为几家公司开发 他
  • 如何在 Flutter 中恢复上次路由

    我正在开发 Flutter 应用程序 但遇到了问题 在我的 main dart 中 我设置了一个名为 FirstScreen 的主路由 然后用户可以转到 LoginScreen 登录帐户 因此 如果我按主页按钮 然后尝试重新打开应用程序 出
  • 如何在不同的分辨率/屏幕上提供相同的应用程序

    Scenario 您需要在不同的屏幕上展示相同的应用程序 假设标准的 15 英寸 17 英寸 便携式 10 英寸和移动 4 英寸 可能在不同的分辨率下工作 Question 您是否尝试采用一种根据可用空间重新排列的流动布局 或者您是否滚动
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 仅针对 Rake 任务运行初始化程序

    我希望在执行 Rake 任务时运行某个初始化程序 但在运行 Rails 服务器时不运行 区分 Rake 调用和服务器调用的最佳方法是什么 Rake 允许您指定任务的依赖关系 最好的建议操作是将特定于 rake 的初始化放入其自己的任务中 而
  • 如何垂直对齐div内的图像

    如何在包含的内容中对齐图像div Example 在我的示例中 我需要将 img in the div with class frame div class frame style height 25px img src http jsfi
  • 如何正确编写AttributeSet的XML?

    我想创建一个面板适用于 Android 平台的其他小部件 http code google com p android misc widgets 在运行时 XmlPullParser parser getResources getXml R
  • PDF 在 Safari 中隐藏 Jquery Modal

    这是与我有关的事情this https stackoverflow com questions 24052681 pdf hide jquery modal in ie问题 在 IE 中 我在对话框中使用 iframe 解决了问题 所以它工
  • Facebook Graph API event-id/comments?since=2014-02-01&until=2014-02-10 ,日期过滤器无效

    我试图通过定位此 URL 来发表对特定事件的评论 https graph facebook com 1466384840257158 comments 我正在传递 user access token 我目前对此事件有两条评论 日 2014
  • MySQL 左连接 WHERE table2.field = "X"

    我有以下表格 pages Field Type Null Key Default Extra page id int 11 NO PRI NULL auto increment type varchar 20 NO NULL
  • Swift 中的 UIAlert 自动消失?

    我有以下代码 Creates Alerts on screen for user func notifyUser title String message String gt Void let alert UIAlertController
  • 模拟pytest中的异常终止

    我的多线程应用程序遇到了一个错误 主线程的任何异常终止 例如 未捕获的异常或某些信号 都会导致其他线程之一死锁 并阻止进程干净退出 我解决了这个问题 但我想添加一个测试来防止回归 但是 我不知道如何在 pytest 中模拟异常终止 如果我只
  • RemoteIO 音频单元播放回调中的 AudioBufferList 内容

    我想 拦截 音频数据传送到 iOS 设备扬声器的过程 我相信这可以使用 RemoteIO 音频单元和回调来完成 在下面的playbackCallback中 ioData实际上包含任何音频数据吗 static OSStatus playbac
  • 显示从 json 到 AMP 页面的原始 HTML

    目前 我正在尝试将 AMP 实施到现有的产品页面 但在显示一些数据方面有点困难 我尝试显示的字段来自 json 并包含原始 HTML 如下所示 description h1 section title h1 p section descri
  • 如何调用 Scala 抽象类型的构造函数?

    我试图弄清楚如何调用 Scala 抽象类型的构造函数 class Journey val length Int class PlaneJourney length Int extends Journey length class BoatJ
  • 如何在多个文档中使用 Google Apps 脚本

    我有一个谷歌应用程序脚本 我想在多个文档中使用它 我也可能想稍后在这些文档中更改它 因此我必须使用same所有这些文档中的脚本 而不是该脚本的副本 我知道以下问题可能属于重复问题 但我不愿意接受它的答案 Google Apps 脚本 如何在
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • 在 TypeScript 中,可以在没有“new”关键字的情况下使用类吗?

    TypeScript 是包含类型的 ES6 Javascript 超集 可以使用以下方式声明一个类class关键字并使用实例化new关键字与 Java 中的关键字类似 我想知道 TypeScript 中是否有任何用例可以在不使用new关键词