When a module (for example, moment.js
, knockout
, or big.js
) is added with a <script>
tag like this:
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js">
</script>
that defines a global property (for instance, moment
, ko
, Big
, etc.), how can one access/declare the types on window
(or global
) in Typescript?
For instance,
const x = moment()
const t = ko.observable()
const b = new Big()
How can one set the ambient type of these globals without including the entire moment.js
library? The goal is to have properly typed global references for use with VS Code, tsc
, ts-loader
, or babel-typescript
.
In the case of moment
, the types are found at node_modules/moment/moment.d.ts
, but for other libraries (like knockout
or big.js
), they are located at @types/[module]/index.d.ts
.
This seems like a common issue, yet there isn't a clear guide on how to achieve it.
Here is an example 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"
]
}
Here's an example of 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'),
}
}
and here's how consumption should work:
const v = new Big(1)
const m = moment()
const s = global.Sentry()
const o = ko.observable()
Which may result in red underlines in VS Code indicating errors:
https://i.sstatic.net/dAiPk.png
Knockout works because @types/knockout/index.d.ts
contains:
declare var ko: KnockoutStatic;
declare module "knockout" {
export = ko;
}
I have declared a global Big
on interface Window
similarly.
Unfortunately, Sentry
and moment
(in this situation) do not seem to function correctly, and it's uncertain what steps need to be taken to resolve this issue.