【发布时间】:2018-12-29 00:07:03
【问题描述】:
我有一个 JavaScript 项目,可以简化成这样:
console.log(depA());
console.log(depB());
我正在使用普通的旧 script 标签来引入依赖项:
<html>
<head>
<script src="pkg/depA/index.js"></script>
<script src="pkg/depB/index.js"></script>
<script src="src/index.js"></script>
</head>
</html>
我使用的包是JavaScript包,都是这样的:
function depX() { // Where X is A or B
return 'depX';
}
这两个包都有自己的index.d.ts typings alongside theirindex.js`。
对于包 A,这很简单:
declare function depA(): string;
对于也可以作为模块使用的包B,typings也是一个模块文件:
declare function depB(): string;
export default depB;
就像我说的,这是一个 JavaScript 项目,我正在使用 TypeScript 进行类型检查:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"types": [
"../pkg/depA",
"../pkg/depB",
]
}
}
我使用 compilerOptions.types 引用包类型,因为这是一个纯 JavaScript 项目,我没有使用 NPM 或任何东西来安装包或类型,因为这是 JavaScript 代码,所以没有 import语句或requires(我没有使用 ESM,也没有 CJS 的构建过程),因此 TypeScript 无法知道这些包并且知道以任何其他方式提取它们的类型,但使用compilerOptions.types 明确告知。
问题是,包 B 的类型是模块文件,所以 depB 函数是在模块范围内声明的,而不是在窗口范围内。 depA 和 depB 只是演示,我面临着现实世界的包,所以我没有选择删除 export default 并使打字成为非模块文件,但我可以创建一个拉请求并添加支持,以使打字文件既是窗口全局函数,又是其他消费者完全使用的模块可以导入的模块。
我的问题然后是,如何修改 depB 类型以使其仍然是一个模块文件(并且没有现有的消费者被破坏),但它们也传达 depB 函数存在于窗口范围,所以 TypeScript 知道可以就地调用它,独立,不导入,什么都没有?
在运行时,就是这样,所以打字是问题,他们只是不传达这个让 TypeScript 知道(我认为),所以我问,如何改变它们来做到这一点?
我创建了一个 GitHub repository 来演示问题,有一个关联的公共 Azure 管道运行 TypeScript 类型检查,显示 depA 可以毫无问题地访问,但 depB 在 window 处不可见因为它只是作为一个模块进行通信。
【问题讨论】:
标签: typescript