使用 .d.ts 文件中的类型定义而不导入
Use type definitions from .d.ts file without importing
我正在将 Web 应用程序从纯 Javascript 迁移到 Typescript,并使用 --outFile
编译器选项和 /// <reference path="..."/>
指令将所有单独的文件编译成一个文件。
这很好,因为我可以将我的代码拆分成多个文件,而不必担心浏览器是否支持 import
。
我使用的一个库是 color-js,它在一个名为 color.d.ts
.
的文件中有类型定义
要将它与普通 Javascript 一起使用,我执行以下操作:
index.html:
[...]
<script src="scripts/color-js/color.js"></script>
<script src="main.js"></script>
[...]
main.js/main.ts
let Color = net.brehaut.Color;
[...]
在运行时,这也适用于 Typescript,但在编译期间,我会遇到如下错误:
scripts/cue.ts(4,13): error TS2304: Cannot find name 'net'.
scripts/cue.ts(25,18): error TS2304: Cannot find name 'Color'.
scripts/cue.ts(26,16): error TS2304: Cannot find name 'Color'.
scripts/cue.ts(27,19): error TS2304: Cannot find name 'Color'.
scripts/main.ts(839,52): error TS2304: Cannot find name 'Color'.
scripts/main.ts(1019,20): error TS2304: Cannot find name 'Color'.
scripts/main.ts(1022,16): error TS2304: Cannot find name 'Color'.
有没有办法只使用color.d.ts
中的类型定义来定义编译时的类型,而不将其作为模块导入?
一旦我将它作为一个导入,我就不能再使用 --outFile
而且我还必须使用像 RequireJS 这样的东西,但我没有开始工作。我的浏览器不支持纯 ES6 或 ES5 导入。
我想也许 /// <reference types="..."
会做那件事,但那似乎有别的用途。
我希望在这里为编译器抱怨的内容、原因以及修复方法提供一些易于理解的上下文。不幸的是,您描述的模块导入限制可能是您需要解决的另一个问题(我认为 AMD 和 SystemJS 将是您使用 --outFile 的唯一选择,但稍后请参阅我的翻译说明。)
您在问题中引用了三斜杠指令
/// <reference types="..."
这是告诉编译器关于 TS 声明文件中的类型依赖关系的指令 (.d.ts
) -- 并不完全需要,因为我们正在编写 TS 而不是声明文件。我们想要包含一个缺失的声明文件,该文件已经存在于某处。请注意,TypeScript 确实非常努力地尝试为开发人员自动解析和包含类型声明文件,但是像 color-js 这样的库没有在 package.json
中指定类型位置,也不使用类型或 @types 约定,编译器就是找不到它。
您可能不想通过声明全局 any
变量来解决此问题,从而放弃智能感知的好处。有一个名为 paths
的记录不足的对象,我们可以将其添加到我们的 tsconfig.json
编译器选项中,这就是我们如何通知编译器查找类型的其他位置,而不是修改自动加载行为,例如typesRoot 或 types 选项。这是一个似乎运行良好的 tsconfig.json
文件示例:
{
"compilerOptions": {
"module": "system",
"target": "es5",
"allowJs": true,
"outFile": "./dist/main.js",
"rootDir": "./src",
"baseUrl": "./",
"paths": {
"*": ["color-js", "./node_modules/color-js/color.d.ts"]
}
},
"exclude": ["dist"]
}
这个 paths
条目告诉编译器的是解析字符串 "color-js" 的任何导入,而不是将模块解析为 JS 文件,抓取 color.d.ts 作为所需的模块而不是从指定的路径。
示例 TS(或 JS!)文件可能如下所示:
import Color from "color-js";
let colorManager = Color();
let twenty = colorManager.setRed(20).getRed();
虽然此解决方案使用 import 关键字,但有人认为,由于我们正在使用上述 tsconfig.json 转译到输出文件(读作:它是单个文件!),所以我们不必担心关于 import 关键字使其进入结果 main.js.
假设此配置不符合您的用例,您仍然发现自己正在寻找一种无需导入模块即可使用类型声明的方法。如果你真的没有其他选择,使用任何类型的变量这样的 hack 是最后的选择。
大多数声明文件在这方面都是全有或全无,因为在幕后实际从 .d.ts 文件(包括 color-js)导出的是一个可以构建 Color 实例的函数.这就是 let colorManager = Color();
行的全部内容,除了有关函数构建内容的类型信息外,我们还使用导出的构建器。正如您所注意到的,在 运行-时间我们可能仍然很好,但就编译器而言,如果我们不能导入类型化函数并调用它,那么构建就完蛋了。
Typescript 3.8 使用 import type {} from '...'
语法添加了此功能:
import type only imports declarations to be used for type annotations and declarations. It always gets fully erased, so there’s no remnant of it at runtime. Similarly, export type only provides an export that can be used for type contexts, and is also erased from TypeScript’s output.
It’s important to note that classes have a value at runtime and a type at design-time, and the use is context-sensitive. When using import type to import a class, you can’t do things like extend from it.
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html
我正在将 Web 应用程序从纯 Javascript 迁移到 Typescript,并使用 --outFile
编译器选项和 /// <reference path="..."/>
指令将所有单独的文件编译成一个文件。
这很好,因为我可以将我的代码拆分成多个文件,而不必担心浏览器是否支持 import
。
我使用的一个库是 color-js,它在一个名为 color.d.ts
.
要将它与普通 Javascript 一起使用,我执行以下操作:
index.html:
[...]
<script src="scripts/color-js/color.js"></script>
<script src="main.js"></script>
[...]
main.js/main.ts
let Color = net.brehaut.Color;
[...]
在运行时,这也适用于 Typescript,但在编译期间,我会遇到如下错误:
scripts/cue.ts(4,13): error TS2304: Cannot find name 'net'.
scripts/cue.ts(25,18): error TS2304: Cannot find name 'Color'.
scripts/cue.ts(26,16): error TS2304: Cannot find name 'Color'.
scripts/cue.ts(27,19): error TS2304: Cannot find name 'Color'.
scripts/main.ts(839,52): error TS2304: Cannot find name 'Color'.
scripts/main.ts(1019,20): error TS2304: Cannot find name 'Color'.
scripts/main.ts(1022,16): error TS2304: Cannot find name 'Color'.
有没有办法只使用color.d.ts
中的类型定义来定义编译时的类型,而不将其作为模块导入?
一旦我将它作为一个导入,我就不能再使用 --outFile
而且我还必须使用像 RequireJS 这样的东西,但我没有开始工作。我的浏览器不支持纯 ES6 或 ES5 导入。
我想也许 /// <reference types="..."
会做那件事,但那似乎有别的用途。
我希望在这里为编译器抱怨的内容、原因以及修复方法提供一些易于理解的上下文。不幸的是,您描述的模块导入限制可能是您需要解决的另一个问题(我认为 AMD 和 SystemJS 将是您使用 --outFile 的唯一选择,但稍后请参阅我的翻译说明。)
您在问题中引用了三斜杠指令
/// <reference types="..."
这是告诉编译器关于 TS 声明文件中的类型依赖关系的指令 (.d.ts
) -- 并不完全需要,因为我们正在编写 TS 而不是声明文件。我们想要包含一个缺失的声明文件,该文件已经存在于某处。请注意,TypeScript 确实非常努力地尝试为开发人员自动解析和包含类型声明文件,但是像 color-js 这样的库没有在 package.json
中指定类型位置,也不使用类型或 @types 约定,编译器就是找不到它。
您可能不想通过声明全局 any
变量来解决此问题,从而放弃智能感知的好处。有一个名为 paths
的记录不足的对象,我们可以将其添加到我们的 tsconfig.json
编译器选项中,这就是我们如何通知编译器查找类型的其他位置,而不是修改自动加载行为,例如typesRoot 或 types 选项。这是一个似乎运行良好的 tsconfig.json
文件示例:
{
"compilerOptions": {
"module": "system",
"target": "es5",
"allowJs": true,
"outFile": "./dist/main.js",
"rootDir": "./src",
"baseUrl": "./",
"paths": {
"*": ["color-js", "./node_modules/color-js/color.d.ts"]
}
},
"exclude": ["dist"]
}
这个 paths
条目告诉编译器的是解析字符串 "color-js" 的任何导入,而不是将模块解析为 JS 文件,抓取 color.d.ts 作为所需的模块而不是从指定的路径。
示例 TS(或 JS!)文件可能如下所示:
import Color from "color-js";
let colorManager = Color();
let twenty = colorManager.setRed(20).getRed();
虽然此解决方案使用 import 关键字,但有人认为,由于我们正在使用上述 tsconfig.json 转译到输出文件(读作:它是单个文件!),所以我们不必担心关于 import 关键字使其进入结果 main.js.
假设此配置不符合您的用例,您仍然发现自己正在寻找一种无需导入模块即可使用类型声明的方法。如果你真的没有其他选择,使用任何类型的变量这样的 hack 是最后的选择。
大多数声明文件在这方面都是全有或全无,因为在幕后实际从 .d.ts 文件(包括 color-js)导出的是一个可以构建 Color 实例的函数.这就是 let colorManager = Color();
行的全部内容,除了有关函数构建内容的类型信息外,我们还使用导出的构建器。正如您所注意到的,在 运行-时间我们可能仍然很好,但就编译器而言,如果我们不能导入类型化函数并调用它,那么构建就完蛋了。
Typescript 3.8 使用 import type {} from '...'
语法添加了此功能:
import type only imports declarations to be used for type annotations and declarations. It always gets fully erased, so there’s no remnant of it at runtime. Similarly, export type only provides an export that can be used for type contexts, and is also erased from TypeScript’s output.
It’s important to note that classes have a value at runtime and a type at design-time, and the use is context-sensitive. When using import type to import a class, you can’t do things like extend from it.
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html