如果一个模块(例如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等),如何在类型记录中访问/声明window (或global)上的类型。
例如
const x = moment()
const t = ko.observable()
const b = new Big()如何在不包括整个moment.js库的情况下设置这些全局的环境类型?目标是让VS代码和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上声明了一个全局的interface Window。
不幸的是,Sentry和moment (在本例中)似乎不起作用,而且不清楚为什么或如何才能修复这个问题。
发布于 2019-05-21 07:33:52
您有正确的想法,您需要使用import类型来获取导入中的类型,您需要在global中声明变量。问题是您要在Window上声明属性。虽然分配给Window的任何键都是全局变量,但类型记录并不反映这一点。您可以在全局范围内直接声明变量。
declare global {
export var moment: typeof import('moment');
export var Sentry: typeof import('@sentry/browser');
}
const m = moment()
Sentry.init({}) // Sentry() does not seem like it should work according to docs发布于 2019-05-21 01:00:17
这个问题并不是特别针对一种类型的平台,但我将告诉您如何使moment在角度上工作。
首先,您不应该从脚本URL加载。您应该运行npm install moment将其放入node_modules文件夹中。这将确保它被打包到应用程序的小型化版本中。你不必这么做,但这是强烈推荐的。
"scripts": [
"node_modules/jquery/dist/jquery.slim.min.js",
"node_modules/moment/moment.js",
...
]不管上面的情况如何,一旦在tsconfig (或angular.json)中链接了脚本,使用就像文件顶部的下面一行一样简单:
import * as moment from 'moment';
对于大多数具有对象的库,例如shortid、linq和lodash,我倾向于使用这种语法。
其他库可以更好地处理declare var语句。例如,我发现jQuery可以通过这种方式更好地工作。
declare var $
Autocomplete
如果您正在寻找自动完成,则需要为库加载一个.d.ts文件。moment的npm包附带了一个,但是有些库需要为此安装另一个npm包(例如@types/lodash、@types/jquery)。
Visual自动完成依赖于.d.ts文件来识别类型。配置此功能的文档位于这里,可以对其进行配置(参见下面的注释)。
https://stackoverflow.com/questions/56190515
复制相似问题