如何从现有的JavaScript库生成一个.d.ts“typings”定义文件?

我使用了很多库,包括我自己的和第三方的。 我看到“打字”目录包含一些Jquery和WinRT …但他们是如何创build的?

有几个选项可供您使用,具体取决于所讨论的库,它是如何写入的以及您要查找的准确度。 让我们回顾一下选项,大致按照合意的顺序排列。

也许它已经存在了

首先检查DefinitelyTyped( https://github.com/DefinitelyTyped/DefinitelyTyped )。 这是一个社区回购,完全是由数千个.d.ts文件组成的,很可能你正在使用的东西已经存在。 您还应该检查TypeSearch( https://microsoft.github.io/TypeSearch/ ),它是NPM发布的.d.ts文件的search引擎; 这将比DefinitelyTyped有更多的定义。 一些模块也将自己的定义作为其NPM分发的一部分,所以在尝试编写自己的模块之前也要看看是否属于这种情况。

也许你不需要一个

TypeScript现在支持--allowJs标志,并将在.js文件中创build更多基于JS的推断。 您可以尝试在编译时join.js文件以及--allowJs设置,看看这是否能给您足够好的types信息。 TypeScript会识别这些文件中的ES5风格的类和JSDoc注释,但如果库以奇怪的方式初始化自己,可能会被绊倒。

开始使用--allowJs

如果--allowJs给了你不错的结果,并且你想自己写一个更好的定义文件,那么你可以把--allowJs--declaration结合起来,看看TypeScript对库types的“最佳猜测”。 这将给你一个体面的起点,如果JSDoc评论写得很好,编译器能够find它们,那么它可能和手写的文件一样好。

开始使用dts-gen

如果--allowJs不起作用,您可能需要使用dts-gen( https://github.com/Microsoft/dts-gen )来获取起点。 此工具使用对象的运行时形状来准确枚举所有可用的属性。 从好的一面来看,这样做很准确,但是这个工具还不支持抓取JSDoc注释来填充其他types。 你这样运行:

 npm install -g dts-gen dts-gen -m <your-module> 

这将在当前文件夹中生成your-module.d.ts

点击贪睡button

如果你只是想稍后再做,并且没有一段时间的types,现在可以在TypeScript 2.0中编写

 declare module "foo"; 

这将允许您importtypes为any"foo"模块。 如果你有一个你想要在以后处理的全球,只需写

 declare const foo: any; 

这会给你一个foovariables。

你可以像使用Ryan描述的那样使用tsc --declaration fileName.ts ,或者你可以在tsconfig.json compilerOptions下指定declaration: true ,假设你的项目已经有了tsconfig.json

处理这个问题的最好方法(如果声明文件在DefinitelyTyped上不可用)是仅为您使用的内容写入声明,而不是整个库。 这大大减less了工作量 – 另外,编译器也可以通过抱怨丢失的方法来帮忙。

正如Ryan所说,tsc编译器有一个开关--declaration ,用于从.ts文件生成一个.d.ts文件。 另外请注意(禁止bug)TypeScript应该能够编译Javascript,所以你可以将现有的javascript代码传递给tsc编译器。

我会寻找你的第三方JS库,支持脚本#或SharpKit现有的映射。 这些C#到.js交叉编译器的用户将遇到您现在面临的问题,可能已经发布了一个开源程序来扫描您的第三方库并转换为骨架C#类。 如果是这样的黑客扫描器程序生成TypeScript代替C#。

否则,将第三方库的C#公共接口转换为TypeScript定义可能比通过阅读源代码JavaScript更简单。

我特别感兴趣的是Sencha的ExtJS RIA框架,并且我知道已经有一些项目被发布来生成Script#或者SharpKit的C#解释

下面是一些PowerShell,它创build了一个单一的TypeScript定义文件,一个包含多个带有现代JavaScript的*.js文件的库。

首先,将所有扩展名更改为.ts

 Get-ChildItem | foreach { Rename-Item $_ $_.Name.Replace(".js", ".ts") } 

其次,使用TypeScript编译器生成定义文件。 会有一堆编译器错误,但我们可以忽略这些错误。

 Get-ChildItem | foreach { tsc $_.Name } 

最后,将所有*.d.ts文件合并到一个*.d.ts文件中,删除import语句并从每个导出语句中删除default

 Remove-Item index.d.ts; Get-ChildItem -Path *.d.ts -Exclude "Index.d.ts" | ` foreach { Get-Content $_ } | ` where { !$_.ToString().StartsWith("import") } | ` foreach { $_.Replace("export default", "export") } | ` foreach { Add-Content index.d.ts $_ } 

这以包含许多定义的单个可用的index.d.ts文件结束。