从 JavaScript 正确调用 TypeScript 代码

IT技术 javascript typescript
2021-03-18 12:10:15

在我们的大型企业项目中,我们面临的情况似乎在 Internet 上的文章和帖子中没有得到很好的描述。

我们需要将支持 SPA 的现有 JavaScript 基础结构代码与其他团队在 TypeScript 上开发的代码集成在一起。对于许多政治限制和可用的开发资源,我们不能彻底改变方法(即只选择一种语言)。而且我们完全理解,将用不同语言编写的两个基础设施集成在一起可能不是一个好主意。

我们仍然需要评估从 JavaScript 代码调用 TypeScript 的影响和最佳实践。

TypeScript 基本上被编译成 JavaScript 的理由似乎很模糊,因为没有关于如何正确使用从手写 JavaScript 编译的 JavaScript 以及隐藏警告(或替代方法)的主题的信息的可靠来源。

当 TypeScript 代码需要调用 JavaScript 时,相反的情况似乎也得到了很好的描述。

关于这个话题有什么深刻的想法吗?

UPD

具体来说,这里是我们现在正在寻求答案的问题列表:

  • 广泛使用泛型、类层次结构、接口的 TypeScript API 的 JavaScript 形式是什么?
  • 捆绑、缩小、AMD 有什么问题吗?
  • 是否可以使用 TypeScript 编写的基本 Angular 控制器和继承其功能的其他 JavaScript Angular 控制器?有哪些注意事项?

其实我们认为我们还没有把所有的问题都浮出水面。他们在对这个话题进行了几个小时的思考后才出现。

5个回答

TypeScript 本质上被编译成 JavaScript 的理由似乎是模糊的,因为没有关于如何正确使用从手写 JavaScript 编译的 JavaScript 以及隐藏警告的主题的信息的可靠来源

从 JavaScript 使用 TypeScript 与从 TypeScript 使用 TypeScript 或从 JavaScript 使用 JavaScript 相同。例如,假设您在 TypeScript 中有一个函数:

function f(n: number) { return 'the number is ' + n; }

要从 TypeScript 调用此函数,您可以编写

var x = f(42);

要从 JavaScript 调用此函数,您需要编写

var x = f(42);

假设您在 TypeScript 中有一个类:

class MyClass { /* ... */ }

要从 TypeScript 使用这个类,你应该写

var c = new MyClass();

要从 JavaScript 使用这个类,你需要编写

var c = new MyClass();

换句话说,它完全一样没有给出指导,因为不需要。

你想得太多了。这里真的没有什么更复杂的事情了。您列出的所有内容都是可能且简单的。
2021-04-20 12:10:15
至于目前,我们还没有找到对我在上面的评论中提到的任何问题的全面答案。说这是可能的和直接的可能是不够的。我可能需要用与使用泛型、类层次结构、缩小、AMD 和这种性质的东西相关的问题来更新原始问题
2021-04-21 12:10:15
你能发布一个更具体的例子吗?
2021-05-03 12:10:15
谢谢你的回答。当您遇到类似返回“Hello world!”的函数时,情况就变得微不足道了。或“爸爸你好!”。但是,当 The Enterprise 中的某个人为您提供使用广泛泛型、接口和继承的 TypeScript 框架/基础结构代码时,这并不是那么简单。由于我们只是在评估警告,我们仍然认为缩小、捆绑、AMD 和其他类似的事情可能会产生很大的影响
2021-05-06 12:10:15
只是我不能。这个问题不是关于一个特定的问题。这个问题是高层次的,与需要制定的战略有关。在上面的评论中提供了一些高级考虑因素,我们正在寻求对需要注意的不同不那么明显方面的深思熟虑的解释(即是否有可能在 TypeScript 中为 Angular 控制器提供基类以及其他继承自它的功能的 JavaScript Angular 控制器)
2021-05-16 12:10:15

简单地说,如果你必须在你自己的使用 JavaScript 的项目中集成/使用一个用 Typescript 编写的库,你将使用编译后的 JavaScript API!

你基本上扔掉了 TypeScript 比纯 JavaScript 带来的好处。

这意味着你不必关心任何特定于 TypeScript 的东西,比如泛型等。你只需要使用 TypeScript 库的编译输出......

举个例子,去http://www.typescriptlang.org/Playground 选择“演练:泛型”。在右侧,您应该会看到已编译的 JavaScript。它没有泛型或任何特殊的东西,它仍然是纯 JavaScript。这就是你必须面对的...

对于您的“特定”问题:

  • 广泛使用泛型、类层次结构、接口的 TypeScript API 的 JavaScript 形式是什么? 往上看。它将是纯正的旧 Javascript。对你没有区别。
  • 捆绑、缩小、AMD 有什么问题吗? 不,因为编译后的 TypeScript 是纯 JavaScript 并且可以缩小等......
  • 是否可以使用 TypeScript 编写的基本 Angular 控制器和继承其功能的其他 JavaScript Angular 控制器?有哪些注意事项? 是的,当然你可以用编译后的 JavaScript 做任何你想做的事。

使用 Typescirpt 编译的 JavaScript 的唯一缺点是,你扔掉了 TypeScript 可以给你的很棒的功能,比如......类型......如果其他团队已经在这条路线上,你可能需要考虑编写你的也参与 TypeScript ;)

最初我是在我最初的问题中寻求这些问题的答案,但似乎我们必须自己揭示它们(如果时间预算允许 - 否则我们将简单地建议不要使用 TS)
2021-04-28 12:10:15
所以可能我们最终需要权衡这些好处与带来一定程度不可预测性 (TS) 的附加方面相关的缺点
2021-05-01 12:10:15
感谢您指出 Playground 更像是一个关于如何将 TS 编译成 JS 的案例研究。它只给出了基本的线索。仍然假设我们正在为大型企业应用程序开发基础结构代码,一些担忧仍然模糊。未来我们是否会面临 TS 在 JS 中如何使用更新版本的 TS 编译的任何重大变化?如果我们决定使用较新版本的 Angular 会发生什么?最终——我们的代码将来会与 ECMAScript6 兼容吗?
2021-05-04 12:10:15
总的来说,很难预测 TS 或 Angular 的未来会带来什么,但是想想如果 Angular 实现了重大更改,你的 javascript 会发生什么?您必须更改您的 JavaScript。所以这不是不使用 TS 的理由,对吗?;) 相反,由于可用的工具,重构 TS 代码会容易得多……您还可以在编译 TS 时选择要针对的标准(ECMAScript 版本)。因此,如果您想使用新版本,TS 已经完全准备好并且已经支持某些功能......
2021-05-04 12:10:15
你可能完全正确。我们只是想为将近一百名企业开发人员的项目制定一个可预测的路线图,说明如何为基础设施和应用程序级前端代码构建 API,以便在可预见的未来面临最少的问题。目前我们有更多的 JS 代码,只是建议在那里引入某种程度的 TS 代码,而不是在 TS 中重写所有内容。您关于重构和工具的观点是完全正确的。
2021-05-17 12:10:15

我认为不是typescript问题。

您可以在 Cofeescript 、 dart 、 traceur 或任何其他转译器中看到相同的“问题”(问题,不是问题)。

Javascript 作为一个平台,非常容易受到开发人员的经验、语言理解和技能的影响。(像任何其他语言一样?)

如果有人很难阅读 TS 生成的 JS(IMMO 对人类非常友好),我认为阅读手工编码的凌乱 JS 不会有更好的运气。

另外,您总是拥有带有接口和更自然的 OOP 方式的 TS 源代码。

合并 OOP 和结构的好处超过了缺点(如果有的话)。

IDE 支持很棒(Webstorm、Visual Studio),你实际上可以重构!

而且你已经限定了 lambdas :)

下一次迭代的 EcmaScript 将非常像今天的 TS(没有可选的类型安全和一些细节)。

如果“Js 团队”中的某个人使用 traceour 或其他任何东西跳转到 ES6,会发生什么,你会关心吗?。您只需坚持module提供的 api 并使用它。

接口和泛型在 JS 端没有任何痕迹。它的*可选设计时帮助。

关于 budling 和 minification 的事情,它和 JS 一样,没有区别,+ 你可以跳过一步,用 TS 将所有内容复制到 1 个输出文件

恕我直言,解决方案是升级、module化(serioulsy)、测试(如果用自我记录的目的编写非常有帮助)和文档。

这实际上并不复杂。. . 您必须了解的第一件事是,该组件是通过 angular 创建为对象的,它包含来自 api 的所有数据、组件、对象和内容,因此您不能让 JavaScript 创建一个新的,它会为空,实际上不会包含您的表单数据。

为了解决这个问题,您需要向您的站点添加一个资产,一个包含一个变量的简单文件就可以了,然后将其添加到您的应用程序中,然后将其导入并在您的初始化中进行设置

我在下面概述了如何将 JS 变量导入 angular,但这里有一个更详细的链接:
如何在 Angular 5 中从 Typescript 调用 JavaScript 函数?

所以添加包含以下内容的js文件:

var formComponent = null;

然后将其添加到您的应用程序 (angular.json)

"scripts": [
    "src/assets/js/formScripting.js"
]

然后将其导入到您的“导入”下的组件中

declare var formComponent: any;

然后在你的初始化和销毁​​上分配你的对象

ngOnInit() {
    formComponent = this; 
}

ngOnDestroy(): any {
    formComponent = null;
}


//a function in your class that you want to call for test purposes
doAngularThing() {
    console.log('Typescript called from JS:')
}

从那时起,在任何 javascript 函数中,您所要做的就是调用:

formComponent.doAngularThing();

由于 formComponent 对象被分配给 this,它是一个指向加载组件的 angular 对象的指针

  • 广泛使用泛型、类层次结构、接口的 TypeScript API 的 JavaScript 形式是什么?

Typescript 在编译期间擦除类型信息,包括泛型参数。这意味着您只需省略 javascript 中的类型参数。

  • 捆绑、缩小、AMD 是否有任何问题?

不。

  • 是否可以使用 TypeScript 编写的基本 Angular 控制器和继承其功能的其他 JavaScript Angular 控制器?有哪些注意事项?

是的,这是可能的。没有任何警告。

一般解决方案:

一般来说,对于typescript和 javascript 之间的任何互操作性问题,都有一个简单的解决方案。到互操作发生时,typescript已全部编译为 javascript。因此,如果您担心如何使用 typescript,只需将其编译为 javascript。然后您正在与 javascript 进行互操作。

如果仍然有人写一篇文章来消除与企业团队采用任何现代技术相关的 FUD,这可能是一个好主意,因为企业团队通常会面临很多阻力。并减少与集成相关的学习曲线。令人惊讶的是,到目前为止没有人这样做。
2021-04-22 12:10:15
然而事情似乎并没有那么简单。例如,这里的walkercoderanger.com/blog/2014/02/typescript-isnt-the-answer人们正在谈论我们可能必须注意的“this”关键字问题。
2021-04-30 12:10:15
直到今天,我才意识到有任何 FUD。无论如何,本文档可能会有所帮助。就语言规范而言,它的可读性很强。 typescriptlang.org/Content/...
2021-05-06 12:10:15
您是在谈论与 javascript 的互操作性吗?还是javascript中的缺陷?this博客上的批评thistypescript中的行为就像this在 javascript 中一样。互操作性怎么可能更简单?
2021-05-07 12:10:15
该博客展示了在 TypeScript 中的类范围内使用的“this”。当 JS 中没有类时,它如何表现得像 JS 中的“this”?这让我们更接近讨论的问题——是否有一套全面的规则来说明如何从编译后的代码中正确设置我们的期望,或者我们只需要放松并接受“一切都以类似方式运行”的模糊声明?另一种情况是枚举。我们只需要透露我们必须在 JS 中使用整数代码而不是在 TS 中使用名称
2021-05-12 12:10:15