从 JavaScript 正确调用 TypeScript 代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26427722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling properly TypeScript code from JavaScript
提问by xenn_33
On our big enterprise project we faced a situation that seems not to be very well described in the articles and the posts available in the Internet.
在我们的大型企业项目中,我们面临的情况似乎在 Internet 上的文章和帖子中没有得到很好的描述。
We need to integrate our existing JavaScript infrastructural code that supports SPA with the code that is being developed by the other team on TypeScript. We can't drastically change the approach (i.e. just pick a single language) for many political limitations and the development resources available. And we fully understand that's probably it's not a good idea to integrate two pieces of infrastructure together that are written on different languages.
我们需要将支持 SPA 的现有 JavaScript 基础结构代码与其他团队在 TypeScript 上开发的代码集成在一起。对于许多限制和可用的开发资源,我们不能彻底改变方法(即只选择一种语言)。我们完全理解,将使用不同语言编写的两个基础设施集成在一起可能不是一个好主意。
Still we need to evaluate the impact and best practices of calling TypeScript from JavaScript code.
我们仍然需要评估从 JavaScript 代码调用 TypeScript 的影响和最佳实践。
The justification that TypeScript is essentially compiled into JavaScript seems to be obscure because there are no trustful sources on information on the topic on how to properly consume that compiled JavaScript from handwritten JavaScript and what are the hidden caveats (or alternatives).
TypeScript 基本上被编译成 JavaScript 的理由似乎是模糊的,因为没有关于如何正确使用从手写 JavaScript 编译的 JavaScript 以及隐藏警告(或替代方法)的主题的信息的可靠来源。
It also seems that the opposite situation when TypeScript code needs to call JavaScript is surprisingly very well described.
当 TypeScript 代码需要调用 JavaScript 时,相反的情况似乎也得到了很好的描述。
Any profound thoughts on the topic?
对这个话题有什么深刻的想法吗?
UPD
UPD
Specifically here is the list of questions we are seeking the answers now:
具体来说,这里是我们现在正在寻求答案的问题列表:
- what will be the JavaScript shape of the TypeScript API that extensively uses generics, class hierarchies, interfaces?
- are there any issues with bundling, minification, AMD?
- is it possible to have the basic Angular controller written in TypeScript and the other JavaScript Angular controller that inherits the functionality from it? What will be the caveats?
- 广泛使用泛型、类层次结构、接口的 TypeScript API 的 JavaScript 形式是什么?
- 捆绑、缩小、AMD 有什么问题吗?
- 是否可以使用 TypeScript 编写的基本 Angular 控制器和继承其功能的其他 JavaScript Angular 控制器?有哪些注意事项?
Actually we think that we haven't surfaced all the questions yet. They've emerged just after a couple of hours of thinking on that topic.
其实我们认为我们还没有把所有的问题都浮出水面。他们在对这个话题进行了几个小时的思考后才出现。
采纳答案by MichaC
Simply said, if you have to integrate/use a library which is written in Typescript in your own project which uses JavaScript, you will use the compiled JavaScript API!
简单地说,如果你必须在你自己的使用 JavaScript 的项目中集成/使用一个用 Typescript 编写的库,你将使用编译后的 JavaScript API!
You basically throw away everything which TypeScript brings in terms of benefit over pure JavaScript.
你基本上扔掉了 TypeScript 比纯 JavaScript 带来的好处。
Meaning you don't have to care about anything specific to TypeScript, like generics etc. You only have to work with the compiled output of the TypeScript library...
这意味着你不必关心任何特定于 TypeScript 的东西,比如泛型等。你只需要使用 TypeScript 库的编译输出......
To give you an example, go to http://www.typescriptlang.org/PlaygroundSelect "Walkthrough: Generics". On the right you should see the compiled JavaScript. It has no generics or anything special, it still is pure JavaScript. That's what you have to deal with...
举个例子,去http://www.typescriptlang.org/Playground选择“演练:泛型”。在右侧,您应该会看到已编译的 JavaScript。它没有泛型或任何特殊的东西,它仍然是纯 JavaScript。这就是你必须面对的...
to your "specific" questions:
对于您的“特定”问题:
- what will be the JavaScript shape of the TypeScript API that extensively uses generics, class hierarchies, interfaces?See above. It will be plain good old Javascript. No difference for you.
- are there any issues with bundling, minification, AMD?No, because compiled TypeScript is plain JavaScript and can be minified etc...
- is it possible to have the basic Angular controller written in TypeScript and the other JavaScript Angular controller that inherits the functionality from it? What will be the caveats?Yes of course you can do whatever you want with the compiled JavaScript.
- 广泛使用泛型、类层次结构、接口的 TypeScript API 的 JavaScript 形式是什么?看上面。它将是纯正的旧 Javascript。对你没有区别。
- 捆绑、缩小、AMD 有什么问题吗?不,因为编译的 TypeScript 是纯 JavaScript 并且可以缩小等......
- 是否可以使用 TypeScript 编写的基本 Angular 控制器和继承其功能的其他 JavaScript Angular 控制器?有哪些注意事项?是的,当然你可以用编译好的 JavaScript 做任何你想做的事。
The only disadvantage of using the compiled JavaScript from Typescirpt is, that you throw away the awesome features TypeScript can give you, like... types... If the other team is already on that route, you may want to consider to write your part in TypeScript as well ;)
使用 Typescirpt 编译的 JavaScript 的唯一缺点是,你放弃了 TypeScript 可以给你的很棒的功能,比如......类型......如果其他团队已经在这条路线上,你可能需要考虑编写你的也参与 TypeScript ;)
回答by Ryan Cavanaugh
The justification that TypeScript is essentially compiled into JavaScript seems to be obscure because there are no trustful sources on information on the topic on how to properly consume that compiled JavaScript from handwritten JavaScript and what are the hidden caveats
TypeScript 基本上被编译成 JavaScript 的理由似乎是模糊的,因为没有关于如何正确使用从手写 JavaScript 编译的 JavaScript 以及隐藏警告的主题的信息的可靠来源
Consuming TypeScript from JavaScript is the same as consuming TypeScript from TypeScript, or JavaScript from JavaScript for that matter. For example, let's say you have a function in TypeScript:
从 JavaScript 使用 TypeScript 与从 TypeScript 使用 TypeScript 或从 JavaScript 使用 JavaScript 相同。例如,假设您在 TypeScript 中有一个函数:
function f(n: number) { return 'the number is ' + n; }
To call this function from TypeScript, you would write
要从 TypeScript 调用此函数,您可以编写
var x = f(42);
To call this function from JavaScript, you would write
要从 JavaScript 调用此函数,您需要编写
var x = f(42);
Let's say you have a class in TypeScript:
假设您在 TypeScript 中有一个类:
class MyClass { /* ... */ }
To use this class from TypeScript, you would write
要从 TypeScript 使用这个类,你应该写
var c = new MyClass();
To use this class from JavaScript, you would write
要从 JavaScript 使用这个类,你需要编写
var c = new MyClass();
In other words, it's exactly the same. No guidance has been given because none is needed.
换句话说,它完全一样。没有给出指导,因为不需要。
回答by Dan
I think is not a Typescript problem.
我认为不是打字稿问题。
You could see the same 'issue' (issue,not a problem) with Cofeescript , dart, traceur , or any other transpiler.
您可以在 Cofeescript 、 dart 、 traceur 或任何其他转译器中看到相同的“问题”(问题,不是问题)。
Javascript as a platfom, is very susceptible to devs's experience, language understanding and skills. (like any other language? )
Javascript 作为一个平台,非常容易受到开发人员的经验、语言理解和技能的影响。(像任何其他语言一样?)
If someone has a hardtime reading the TS generated JS (that IMMO is pretty human friendly ) I don't think it will have better luck reading hand-coded messy JS.
如果有人很难阅读 TS 生成的 JS(IMMO 对人类非常友好),我认为阅读手工编码的凌乱 JS 不会有更好的运气。
Plus, you always have the TS's source code with the interfaces and more natural OOP manners.
此外,您始终拥有带有接口和更自然的 OOP 方式的 TS 源代码。
the benefits of incorporating OOP and structure outweight the cons(if there is any).
合并 OOP 和结构的好处超过了缺点(如果有的话)。
IDE support is great (Webstorm , Visual Studio) , you can actually refactor!
IDE 支持很棒(Webstorm、Visual Studio),你实际上可以重构!
And you have scoped lambdas :)
而且你已经限定了 lambdas :)
The next iteration EcmaScript will be very much like what is TS today (without optional type saftey and a few niceties).
下一次迭代的 EcmaScript 将非常像今天的 TS(没有可选的类型安全和一些细节)。
What is gonna happen if somebody in the 'Js team' jump to ES6 with traceour or whatever other thing, will you care?. You will simply stick to the api provided by the module and work with that.
如果“Js 团队”中的某个人使用 traceour 或其他任何东西跳转到 ES6,会发生什么,你会关心吗?。您只需坚持模块提供的 api 并使用它。
Interfaces and Generics and washed up no trace of them on the JS side. its *optional design time help.
接口和泛型在 JS 端没有任何痕迹。它的*可选设计时帮助。
And regarding the budling and minification thing, it will be the same as with JS , no difference , + you could jump one step with TS copilling everything to 1 outputfile
关于 budling 和 minification 的事情,它和 JS 一样,没有区别,+ 你可以跳过一步,用 TS 将所有内容复制到 1 个输出文件
IMMO the solution is level-up , modularize(serioulsy), tests(very helpful if written with self documenting puprposes) and Documentation.
恕我直言,解决方案是升级、模块化(serioulsy)、测试(如果用自我记录的目的编写非常有帮助)和文档。
回答by recursive
- What will be the JavaScript shape of the TypeScript API that extensively uses generics, class hierarchies, interfaces?
- 广泛使用泛型、类层次结构、接口的 TypeScript API 的 JavaScript 形式是什么?
Typescript erases type information during compilation, including generic parameters. This means that you just omit the type parameters in your javascript.
Typescript 在编译期间擦除类型信息,包括泛型参数。这意味着您只需省略 javascript 中的类型参数。
- Are there any issues with bundling, minification, AMD?
- 捆绑、缩小、AMD 是否有任何问题?
No.
不。
- Is it possible to have the basic Angular controller written in TypeScript and the other JavaScript Angular controller that inherits the functionality from it? What will be the caveats?
- 是否有可能用 TypeScript 编写基本的 Angular 控制器和从它继承功能的另一个 JavaScript Angular 控制器?有哪些注意事项?
Yes, it's possible. There are no caveats.
是的,这是可能的。没有任何警告。
General Solution:
一般解决方案:
In general, there is a simple solution for any interoperability concern between typescript and javascript. By the time the interoperating happens, the typescript has all been compiled to javascript. So if you're worried about how to consume typescript, just compile it to javascript. Then you are interoperating with javascript.
一般来说,对于打字稿和 javascript 之间的任何互操作性问题,都有一个简单的解决方案。到互操作发生时,打字稿已全部编译为 javascript。因此,如果您担心如何使用 typescript,只需将其编译为 javascript。然后你正在与 javascript 互操作。
回答by Mike A.
This actually not all too complicated. . . the first thing you have to understand is that the component is created as an object by angular, and it contains all the data, components, objects and stuff from your api's so you can't just go have JavaScript make a new one, it will be empty and won't actually have your form data in it.
这实际上并不复杂。. . 您必须了解的第一件事是,该组件是通过 angular 创建为对象的,它包含来自 api 的所有数据、组件、对象和内容,因此您不能只让 JavaScript 创建一个新的,它会为空,实际上不会包含您的表单数据。
In order to remedy this, you need to add an asset to your site, a simple file with one variable in it is fine, then add it to your app, then import it and set it in your init
为了解决这个问题,您需要向您的站点添加一个资产,一个包含一个变量的简单文件就可以了,然后将其添加到您的应用程序中,然后将其导入并在您的初始化中进行设置
i've outlined how you import a JS variable into angular below, but here's a link with a bit more detail:
How to call JavaScript functions from Typescript in Angular 5?
我在下面概述了如何将 JS 变量导入 angular,但这里有一个更详细的链接:
如何在 Angular 5 中从 Typescript 调用 JavaScript 函数?
so add the js file containing:
所以添加包含以下内容的js文件:
var formComponent = null;
then add it to your app (angular.json)
然后将其添加到您的应用程序 (angular.json)
"scripts": [
"src/assets/js/formScripting.js"
]
then import it to your component right under your "imports"
然后将其导入到您的“导入”下的组件中
declare var formComponent: any;
then assign your object on your init and destroy
然后在你的 init 上分配你的对象并销毁
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:')
}
from that point on, in ANY javascript function all you have to do is call:
从那时起,在任何 javascript 函数中,您所要做的就是调用:
formComponent.doAngularThing();
since the formComponent object was assigned to this, it's a pointer to the angular object that loaded your compoonent
由于 formComponent 对象被分配给 this,它是一个指向加载组件的 angular 对象的指针

