我自己和第三方都在使用很多图书馆。我看到“类型”目录包含一些Jquery和WinRT ...,但是它们是如何创建的呢?
我自己和第三方都在使用很多图书馆。我看到“类型”目录包含一些Jquery和WinRT ...,但是它们是如何创建的呢?
Answers:
根据所涉及的库,它的编写方式以及所需的精度水平,有几种可用的选项供您选择。让我们按可取性的大致降序查看选项。
始终首先检查DefinitelyTyped(https://github.com/DefinitelyTyped/DefinitelyTyped)。这是一个社区仓库,里面装满了成千上万个.d.ts文件,很可能您正在使用的东西已经存在。您还应该检查TypeSearch(https://microsoft.github.io/TypeSearch/),它是NPM发布的.d.ts文件的搜索引擎;这将比DefinitelyTyped具有更多的定义。一些模块也在NPM发行版中提供了自己的定义,因此在尝试编写自己的模块之前,请先查看是否存在这种情况。
TypeScript现在支持该--allowJs
标志,并将在.js文件中进行更多基于JS的推断。您可以尝试在编译中包括.js文件以及--allowJs
设置,以查看是否为您提供了足够好的类型信息。TypeScript可以识别这些文件中的ES5样式类和JSDoc注释之类的东西,但是如果库以一种奇怪的方式初始化自身,它可能会被绊倒。
--allowJs
如果--allowJs
给您不错的结果,并且您想自己编写一个更好的定义文件,则可以将其--allowJs
与--declaration
TypeScript对库类型的“最佳猜测” 结合使用。这将为您提供一个不错的起点,并且如果JSDoc注释写得很好并且编译器能够找到它们,那么它可能与手写文件一样好。
如果--allowJs
不起作用,则可能要使用dts-gen(https://github.com/Microsoft/dts-gen)作为起点。该工具使用对象的运行时形状来精确枚举所有可用属性。从好的方面来说,这往往非常准确,但是该工具尚不支持抓取JSDoc注释来填充其他类型。您可以这样运行:
npm install -g dts-gen
dts-gen -m <your-module>
这将your-module.d.ts
在当前文件夹中生成。
如果您只是想稍后再做,并且暂时不用输入类型,现在可以在TypeScript 2.0中编写
declare module "foo";
这将使您使用类型import
为的"foo"
模块any
。如果您有一家跨国公司要稍后处理,只需写
declare const foo: any;
这会给你一个foo
变量。
--declarations
生成.js
文件和.d.ts
文件,这意味着您只需要运行一个编译即可。
--allowJs
与--declaration
选项不能组合使用(在TypeScript 1.8和2.0中测试)。如果尝试,我会得到:error TS5053: Option 'allowJs' cannot be specified with option 'declaration'
您可以tsc --declaration fileName.ts
像Ryan所描述的那样使用,也可以在假设您的项目已经存在的情况下指定declaration: true
under 。compilerOptions
tsconfig.json
tsconfig.json
tsc --declaration test.ts
出现错误Cannot find name...
,那么在声明它们之前我需要这些类型吗?
declaration: true
到tsconfig.json
文件中吗?
解决此问题的最佳方法(如果DefinitelyTyped上没有声明文件)是仅针对您使用的东西而不是整个库编写声明。这大大减少了工作量-此外,编译器在那里可以通过抱怨缺少方法来提供帮助。
正如Ryan所说,tsc编译器具有一个从文件--declaration
生成.d.ts
文件的开关.ts
。另请注意,(排除错误)TypeScript应该能够编译Javascript,因此您可以将现有的JavaScript代码传递给tsc编译器。
如http://channel9.msdn.com/posts/Anders-Hejlsberg-Steve-Lucco-and-Luke-Hoban-Inside-TypeScript中的描述(00:33:52),他们已经构建了将WebIDL和WinRT元数据转换为TypeScript d.ts
这是一些PowerShell,可创建一个TypeScript定义文件,该文件包含多个库 *.js
使用现代JavaScript文件。
首先,将所有扩展名更改为.ts
。
Get-ChildItem | foreach { Rename-Item $_ $_.Name.Replace(".js", ".ts") }
其次,使用TypeScript编译器生成定义文件。会有很多编译器错误,但是我们可以忽略这些错误。
Get-ChildItem | foreach { tsc $_.Name }
最后,将所有*.d.ts
文件合并为一个index.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
包含许多定义的单个可用文件结束。
创建自己的库时,您可以*.d.ts
使用tsc
(TypeScript Compiler)命令来创建文件, 如下所示:(假设您将库构建到该dist/lib
文件夹中)
tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly
-d
(--declaration
):生成*.d.ts
文件--declarationDir dist/lib
:生成的声明文件的输出目录。--declarationMap
:为每个相应的.d文件生成一个源映射。--emitDeclarationOnly
:仅发出“ .d.ts”声明文件。(没有编译的JS)(请参阅文档有关所有命令行编译器选项,)
或者例如在您的package.json
:
"scripts": {
"build:types": "tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly",
}
然后运行:(yarn build:types
或npm run build:types
)
d.ts
文件并能够使用界面。你有什么例子吗?
*.d.ts
文件,并将它们放在dist/lib
文件夹中。您确实需要tsconfig.json
在项目的根目录中有一个文件,但是该文件仍然可以在项目中正常运行。
我会寻找支持Script#或SharpKit的第三方JS库的现有映射。这些C#到.js交叉编译器的用户将面临您现在面临的问题,并且可能已经发布了一个开源程序来扫描您的第三方库并转换为骨架C#类。如果是这样,请破解扫描程序以生成TypeScript代替C#。
失败的话,将第3方库的C#公共接口转换为TypeScript定义可能比通过阅读源JavaScript进行转换更简单。
我特别感兴趣的是Sencha的ExtJS RIA框架,而且我知道已经发布了一些项目来生成Script#或SharpKit的C#解释。