【发布时间】:2019-10-05 00:40:34
【问题描述】:
如果模块(例如 moment.js、knockout 或 big.js)包含在 <script> 标签中,例如
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js">
</script>
定义一个全局属性(例如moment、ko、Big 等),如何在 Typescript 中访问/声明window(或global)上的类型。
例如
const x = moment()
const t = ko.observable()
const b = new Big()
如何在不包括整个 moment.js 库的情况下设置这些全局变量的环境类型?目标是让 VS Code 和 tsc、ts-loader 或 babel-typescript 使用正确类型的全局引用。
对于moment,类型在node_modules/moment/moment.d.ts 公开,但对于其他库(例如knockout 或big.js),它们在@types/[module]/index.d.ts。
感觉这很常见,但我还没有看到一个很好的工作参考来说明如何完成这个。
这里是 tsconfig:
{
"compilerOptions": {
"target": "ESNext",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"strict": false,
"isolatedModules": false,
"esModuleInterop": true,
"noResolve": false,
"baseUrl": ".",
"paths": {
"*": [
"*",
"js.packages/*"
]
},
"jsx": "preserve",
"outDir": "dist/"
},
"include": [
"js.packages/**/*.ts",
"js.packages/**/*.tsx",
"js.packages/@types/lib.d.ts",
],
"files": [
"services/app/src/entry.js"
],
"exclude": [
"node_modules"
]
}
这是lib.d.ts
declare global {
type Bigable = Big | string | number
interface Window {
Big: typeof import('big.js'),
moment: typeof import('moment'),
Sentry: typeof import('@sentry/browser'),
}
}
这是消费应该如何运作的:
const v = new Big(1)
const m = moment()
const s = global.Sentry()
const o = ko.observable()
在 VS Code 中看起来像这样(红色下划线表示失败):
所以淘汰赛有效,因为@types/knockout/index.d.ts 有:
declare var ko: KnockoutStatic;
declare module "knockout" {
export = ko;
}
而我同样在interface Window 上声明了一个全局Big。
不幸的是,Sentry 和 moment(在此示例中)似乎不起作用,目前尚不清楚为什么或需要做什么来解决此问题。
【问题讨论】:
-
由于所有类型都是 UMD 声明,并且由于 TypeScript 会自动查找
node_modules/[package]和node_modules/@types/[package],因此您不需要做任何特别的事情。请发布您的tsconfig.json。完全可以安装 moment 包来获取类型,同时仍然在运行时从脚本标签加载实现。 -
@AluanHaddad 我已经发布了很多细节,希望能帮助阐明。
-
@TitianCernicova-Dragomir 谢谢;这也是一个很好的问题,你可以从我所做的编辑中看到具体问题的答案是如何不足的。
-
您能否举例说明您想要做什么(即使用情况)?
标签: typescript