我使用了很多自己的和第三方的库。 我看到"typings"目录中包含一些Jquery和WinRT的库...但它们是如何创建的呢?
我使用了很多自己的和第三方的库。 我看到"typings"目录中包含一些Jquery和WinRT的库...但它们是如何创建的呢?
根据所使用的库、它的编写方式以及您需要的准确性水平,有几种选项可供选择。让我们大致按照可取性降序来审查这些选项。
首先,始终要先检查 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";
这将让你使用类型any
导入"foo"
模块。如果你想以后处理全局变量,只需编写:
declare const foo: any;
这将给你一个foo
变量。
你可以按照Ryan所述使用tsc --declaration fileName.ts
,或者在你的tsconfig.json
文件中,在compilerOptions
下指定declaration: true
,前提是你已经有了一个tsconfig.json
文件。
tsc --declaration test.ts
,我会得到错误信息 Cannot find name...
,这是因为我正在尝试创建一个声明文件 :) 所以在声明之前我需要先有这些类型? - Kokodokotsconfig.json
文件中添加declaration: true
吗? - JayKan创建自己的库时,您可以使用 tsc
(TypeScript编译器)命令创建*.d.ts
文件,方法如下:
(假设您正在将库构建到dist/lib
文件夹中)
tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly
-d
(--declaration
):生成*.d.ts
文件。--declarationDir dist/lib
:生成声明文件的输出目录。--declarationMap
:为每个对应的‘.d.ts’文件生成源映射。--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
文件并能够使用接口。你有任何例子吗? - Danosaure*.d.ts
文件并将它们放在dist/lib
文件夹中。你确实需要在项目根目录下有一个tsconfig.json
文件,但这对于项目的正常工作来说应该已经存在了。 - magikMaker如果在DefinitelyTyped上找不到声明文件,最好的解决方法是只为你使用的部分编写声明文件,而不是整个库。这样可以大大减少工作量,此外编译器会通过报告缺失的方法来提供帮助。
正如Ryan所说,tsc编译器有一个开关--declaration
,可以从.ts
文件生成一个.d.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代码,用于创建一个包含多个现代JavaScript文件*.js
的库的单个TypeScript定义文件。
首先,将所有扩展名更改为.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
文件,其中包含许多定义。
import ts from 'typescript';
function createDTsTextsFromJsFilePaths(
jsFileNames: string[]
): Record<string, string> {
const options = {
allowJs: true,
declaration: true,
emitDeclarationOnly: true,
};
// Create a Program with an in-memory emit
const createdFiles: Record<string, string> = {};
const host = ts.createCompilerHost(options);
host.writeFile = (fileName: string, contents: string): void => {
const dtsName = fileName.replace('.js', '.d.ts');
createdFiles[dtsName] = contents;
};
// Prepare and emit the d.ts files
const program = ts.createProgram(jsFileNames, options, host);
program.emit();
return createdFiles;
}
////////////// test code below here ///////////////////////////////////
import fs from 'fs'
const jsTest =
`
"use strict"
function x(){
return {
a: 1,
b: ()=>'hello'
}
}
`;
const jsPath = '/tmp/jstest.js';
fs.writeFileSync(jsPath, jsTest);
const createdFiles = createDTsTextsFromJsFilePaths([jsPath]);
for (const dtsName in createdFiles) {
console.log('================');
console.log(dtsName);
console.log('----------------');
console.log(createdFiles[dtsName]);
}
================
/tmp/jstest.d.ts
----------------
declare function x(): {
a: number;
b: () => string;
};
tsc --declaration FileName.js --allowJs
这个命令将在您当前文件夹中生成一个 d.ts 文件。您需要安装 TypeScript,但不需要成为项目维护者,也不需要设置更大的编译过程。您可以将任何旧的 JavaScript 文件交给它,并尝试为您生成类型定义。
--declarations
选项可以同时生成.js
和.d.ts
两个文件,这意味着你只需要运行一次编译即可。 - Fenton--allowJs
和--declaration
选项不能组合使用。如果尝试这样做,会出现以下错误:error TS5053: Option 'allowJs' cannot be specified with option 'declaration'
。 - Aleksei Zyrianov